Source Code Cross Referenced for AppletClassLoader.java in  » 6.0-JDK-Modules » j2me » sun » applet » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » sun.applet 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)AppletClassLoader.java	1.84 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation. 
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt). 
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA 
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package sun.applet;
029:
030:        import java.net.URL;
031:        import java.net.URLClassLoader;
032:        import java.net.SocketPermission;
033:        import java.net.URLConnection;
034:        import java.net.MalformedURLException;
035:        import java.net.InetAddress;
036:        import java.net.UnknownHostException;
037:        import java.io.File;
038:        import java.io.FilePermission;
039:        import java.io.IOException;
040:        import java.io.InputStream;
041:        import java.util.Enumeration;
042:        import java.util.NoSuchElementException;
043:        import java.security.AccessController;
044:        import java.security.AccessControlContext;
045:        import java.security.PrivilegedAction;
046:        import java.security.PrivilegedExceptionAction;
047:        import java.security.PrivilegedActionException;
048:        import java.security.CodeSource;
049:        import java.security.PermissionCollection;
050:        import sun.awt.AppContext;
051:        import sun.awt.SunToolkit;
052:
053:        /**
054:         * This class defines the class loader for loading applet classes and
055:         * resources. It extends URLClassLoader to search the applet code base
056:         * for the class or resource after checking any loaded JAR files.
057:         */
058:        public class AppletClassLoader extends URLClassLoader {
059:            private URL base; /* applet code base URL */
060:            private CodeSource codesource; /* codesource for the base URL */
061:            private AccessControlContext acc;
062:
063:            /*
064:             * Creates a new AppletClassLoader for the specified base URL.
065:             */
066:            protected AppletClassLoader(URL base) {
067:                super (new URL[0]);
068:                this .base = base;
069:                this .codesource = new CodeSource(base, null);
070:                acc = AccessController.getContext();
071:            }
072:
073:            /*
074:             * Returns the applet code base URL.
075:             */
076:            URL getBaseURL() {
077:                return base;
078:            }
079:
080:            /*
081:             * Returns the URLs used for loading classes and resources.
082:             */
083:            public URL[] getURLs() {
084:                URL[] jars = super .getURLs();
085:                URL[] urls = new URL[jars.length + 1];
086:                System.arraycopy(jars, 0, urls, 0, jars.length);
087:                urls[urls.length - 1] = base;
088:                return urls;
089:            }
090:
091:            /*
092:             * Adds the specified JAR file to the search path of loaded JAR files.
093:             */
094:            void addJar(String name) {
095:                URL url;
096:                try {
097:                    url = new URL(base, name);
098:                } catch (MalformedURLException e) {
099:                    throw new IllegalArgumentException("name");
100:                }
101:                addURL(url);
102:                // DEBUG
103:                //URL[] urls = getURLs();
104:                //for (int i = 0; i < urls.length; i++) {
105:                //    System.out.println("url[" + i + "] = " + urls[i]);
106:                //}
107:            }
108:
109:            /*
110:             * Override loadClass so that class loading errors can be caught in
111:             * order to print better error messages.
112:             */
113:            public synchronized Class loadClass(String name, boolean resolve)
114:                    throws ClassNotFoundException {
115:                // First check if we have permission to access the package. This
116:                // should go away once we've added support for exported packages.
117:                int i = name.lastIndexOf('.');
118:                if (i != -1) {
119:                    SecurityManager sm = System.getSecurityManager();
120:                    if (sm != null)
121:                        sm.checkPackageAccess(name.substring(0, i));
122:                }
123:                try {
124:                    return super .loadClass(name, resolve);
125:                } catch (ClassNotFoundException e) {
126:                    //printError(name, e.getException());
127:                    throw e;
128:                } catch (RuntimeException e) {
129:                    //printError(name, e);
130:                    throw e;
131:                } catch (Error e) {
132:                    //printError(name, e);
133:                    throw e;
134:                }
135:            }
136:
137:            /*
138:             * Finds the applet class with the specified name. First searches
139:             * loaded JAR files then the applet code base for the class.
140:             */
141:            protected Class findClass(String name)
142:                    throws ClassNotFoundException {
143:                // check loaded JAR files
144:                try {
145:                    return super .findClass(name);
146:                } catch (ClassNotFoundException e) {
147:                }
148:                // Otherwise, try loading the class from the code base URL
149:                final String path = name.replace('.', '/').concat(".class");
150:                try {
151:                    byte[] b = (byte[]) AccessController.doPrivileged(
152:                            new PrivilegedExceptionAction() {
153:                                public Object run() throws IOException {
154:                                    return getBytes(new URL(base, path));
155:                                }
156:                            }, acc);
157:                    if (b != null) {
158:                        return defineClass(name, b, 0, b.length, codesource);
159:                    } else {
160:                        throw new ClassNotFoundException(name);
161:                    }
162:                } catch (PrivilegedActionException e) {
163:                    throw new ClassNotFoundException(name, e.getException());
164:                }
165:            }
166:
167:            /**
168:             * Returns the permissions for the given codesource object.
169:             * The implementation of this method first calls super.getPermissions,
170:             * to get the permissions
171:             * granted by the super class, and then adds additional permissions
172:             * based on the URL of the codesource.
173:             * <p>
174:             * If the protocol is "file"
175:             * and the path specifies a file, permission is granted to read all files 
176:             * and (recursively) all files and subdirectories contained in 
177:             * that directory. This is so applets with a codebase of
178:             * file:/blah/some.jar can read in file:/blah/, which is needed to
179:             * be backward compatible. We also add permission to connect back to
180:             * the "localhost".
181:             *
182:             * @param codesource the codesource
183:             * @return the permissions granted to the codesource
184:             */
185:            protected PermissionCollection getPermissions(CodeSource codesource) {
186:                final PermissionCollection perms = super 
187:                        .getPermissions(codesource);
188:                URL url = codesource.getLocation();
189:                if (url.getProtocol().equals("file")) {
190:                    String path = url.getFile()
191:                            .replace('/', File.separatorChar);
192:                    if (!path.endsWith(File.separator)) {
193:                        int endIndex = path.lastIndexOf(File.separatorChar);
194:                        if (endIndex != -1) {
195:                            path = path.substring(0, endIndex + 1) + "-";
196:                            perms.add(new FilePermission(path, "read"));
197:                        }
198:                    }
199:                    perms.add(new SocketPermission("localhost",
200:                            "connect,accept"));
201:                    AccessController.doPrivileged(new PrivilegedAction() {
202:                        public Object run() {
203:                            try {
204:                                String host = InetAddress.getLocalHost()
205:                                        .getHostName();
206:                                perms.add(new SocketPermission(host,
207:                                        "connect,accept"));
208:                            } catch (UnknownHostException uhe) {
209:                            }
210:                            return null;
211:                        }
212:                    });
213:                    if (base.getProtocol().equals("file")) {
214:                        String bpath = base.getFile().replace('/',
215:                                File.separatorChar);
216:                        if (bpath.endsWith(File.separator)) {
217:                            bpath += "-";
218:                        }
219:                        perms.add(new FilePermission(bpath, "read"));
220:                    }
221:                }
222:                return perms;
223:            }
224:
225:            /*
226:             * Returns the contents of the specified URL as an array of bytes.
227:             */
228:            private static byte[] getBytes(URL url) throws IOException {
229:                URLConnection uc = url.openConnection();
230:                if (uc instanceof  java.net.HttpURLConnection) {
231:                    java.net.HttpURLConnection huc = (java.net.HttpURLConnection) uc;
232:                    int code = huc.getResponseCode();
233:                    if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {
234:                        throw new IOException("open HTTP connection failed.");
235:                    }
236:                }
237:                int len = uc.getContentLength();
238:                InputStream in = uc.getInputStream();
239:                byte[] b;
240:                try {
241:                    if (len != -1) {
242:                        // Read exactly len bytes from the input stream
243:                        b = new byte[len];
244:                        while (len > 0) {
245:                            int n = in.read(b, b.length - len, len);
246:                            if (n == -1) {
247:                                throw new IOException("unexpected EOF");
248:                            }
249:                            len -= n;
250:                        }
251:                    } else {
252:                        // Read until end of stream is reached
253:                        b = new byte[1024];
254:                        int total = 0;
255:                        while ((len = in.read(b, total, b.length - total)) != -1) {
256:                            total += len;
257:                            if (total >= b.length) {
258:                                byte[] tmp = new byte[total * 2];
259:                                System.arraycopy(b, 0, tmp, 0, total);
260:                                b = tmp;
261:                            }
262:                        }
263:                        // Trim array to correct size, if necessary
264:                        if (total != b.length) {
265:                            byte[] tmp = new byte[total];
266:                            System.arraycopy(b, 0, tmp, 0, total);
267:                            b = tmp;
268:                        }
269:                    }
270:                } finally {
271:                    in.close();
272:                }
273:                return b;
274:            }
275:
276:            /*
277:             * Finds the applet resource with the specified name. First checks
278:             * loaded JAR files then the applet code base for the resource.
279:             */
280:            public URL findResource(String name) {
281:                // check loaded JAR files
282:                URL url = super .findResource(name);
283:                if (url == null) {
284:                    // otherwise, try the code base
285:                    try {
286:                        url = new URL(base, name);
287:                        // check if resource exists
288:                        if (!resourceExists(url))
289:                            url = null;
290:                    } catch (Exception e) {
291:                        // all exceptions, including security exceptions, are caught
292:                        url = null;
293:                    }
294:                }
295:                return url;
296:            }
297:
298:            private boolean resourceExists(URL url) {
299:                // Check if the resource exists.
300:                // It almost works to just try to do an openConnection() but
301:                // HttpURLConnection will return true on HTTP_BAD_REQUEST
302:                // when the requested name ends in ".html", ".htm", and ".txt"
303:                // and we want to be able to handle these
304:                //
305:                // Also, cannot just open a connection for things like FileURLConnection,
306:                // because they suceed when connecting to a non-existant file.
307:                // So, in those cases we open and close an input stream.
308:                boolean ok = true;
309:                try {
310:                    URLConnection conn = url.openConnection();
311:                    if (conn instanceof  java.net.HttpURLConnection) {
312:                        java.net.HttpURLConnection hconn = (java.net.HttpURLConnection) conn;
313:                        int code = hconn.getResponseCode();
314:                        if (code == java.net.HttpURLConnection.HTTP_OK) {
315:                            return true;
316:                        }
317:                        if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {
318:                            return false;
319:                        }
320:                    } else {
321:                        // our best guess for the other cases
322:                        InputStream is = url.openStream();
323:                        is.close();
324:                    }
325:                } catch (Exception ex) {
326:                    ok = false;
327:                }
328:                return ok;
329:            }
330:
331:            /*
332:             * Returns an enumeration of all the applet resources with the specified
333:             * name. First checks loaded JAR files then the applet code base for all
334:             * available resources.
335:             */
336:            public Enumeration findResources(String name) throws IOException {
337:                URL u = new URL(base, name);
338:                if (!resourceExists(u)) {
339:                    u = null;
340:                }
341:                final Enumeration e = super .findResources(name);
342:                final URL url = u;
343:                return new Enumeration() {
344:                    private boolean done;
345:
346:                    public Object nextElement() {
347:                        if (!done) {
348:                            if (e.hasMoreElements()) {
349:                                return e.nextElement();
350:                            }
351:                            done = true;
352:                            if (url != null) {
353:                                return url;
354:                            }
355:                        }
356:                        throw new NoSuchElementException();
357:                    }
358:
359:                    public boolean hasMoreElements() {
360:                        return !done && (e.hasMoreElements() || url != null);
361:                    }
362:                };
363:            }
364:
365:            /*
366:             * Load and resolve the file specified by the applet tag CODE
367:             * attribute. The argument can either be the relative path
368:             * of the class file itself or just the name of the class.
369:             */
370:            Class loadCode(String name) throws ClassNotFoundException {
371:                // first convert any '/' or native file separator to .
372:                name = name.replace('/', '.');
373:                name = name.replace(File.separatorChar, '.');
374:                // save that name for later
375:                String fullName = name;
376:                // then strip off any suffixes
377:                if (name.endsWith(".class") || name.endsWith(".java")) {
378:                    name = name.substring(0, name.lastIndexOf('.'));
379:                }
380:                try {
381:                    return loadClass(name);
382:                } catch (ClassNotFoundException e) {
383:                }
384:                // then if it didn't end with .java or .class, or in the 
385:                // really pathological case of a class named class or java
386:                return loadClass(fullName);
387:            }
388:
389:            /*
390:             * The threadgroup that the applets loaded by this classloader live
391:             * in. In the sun.* implementation of applets, the security manager's
392:             * (AppletSecurity) getThreadGroup returns the thread group of the 
393:             * first applet on the stack, which is the applet's thread group.
394:             */
395:            private AppletThreadGroup threadGroup;
396:            private AppContext appContext;
397:
398:            synchronized ThreadGroup getThreadGroup() {
399:                if (threadGroup == null || threadGroup.isDestroyed()) {
400:                    AccessController.doPrivileged(new PrivilegedAction() {
401:                        public Object run() {
402:                            threadGroup = new AppletThreadGroup(base
403:                                    + "-threadGroup");
404:                            // threadGroup.setDaemon(true);
405:                            // threadGroup is now destroyed by AppContext.dispose()
406:
407:                            // Create the new AppContext from within a Thread belonging
408:                            // to the newly created ThreadGroup, and wait for the
409:                            // creation to complete before returning from this method.
410:                            AppContextCreator creatorThread = new AppContextCreator(
411:                                    threadGroup);
412:                            // Since this thread will later be used to launch the
413:                            // applet's AWT-event dispatch thread and we want the applet 
414:                            // code executing the AWT callbacks to use their own class
415:                            // loader rather than the system class loader, explicitly
416:                            // set the context class loader to the AppletClassLoader.
417:                            creatorThread
418:                                    .setContextClassLoader(AppletClassLoader.this );
419:                            synchronized (creatorThread.syncObject) {
420:                                creatorThread.start();
421:                                try {
422:                                    creatorThread.syncObject.wait();
423:                                } catch (InterruptedException e) {
424:                                }
425:                                appContext = creatorThread.appContext;
426:                            }
427:                            return null;
428:                        }
429:                    });
430:                }
431:                return threadGroup;
432:            }
433:
434:            /*
435:             * Get the AppContext, if any, corresponding to this AppletClassLoader.
436:             */
437:            AppContext getAppContext() {
438:                return appContext;
439:            }
440:
441:            int usageCount = 0;
442:
443:            /**
444:             * Grab this AppletClassLoader and its ThreadGroup/AppContext, so they
445:             * won't be destroyed.
446:             */
447:            synchronized void grab() {
448:                usageCount++;
449:                getThreadGroup(); // Make sure ThreadGroup/AppContext exist
450:            }
451:
452:            /**
453:             * Release this AppletClassLoader and its ThreadGroup/AppContext.
454:             * If nothing else has grabbed this AppletClassLoader, its ThreadGroup
455:             * and AppContext will be destroyed.
456:             * 
457:             * Because this method may destroy the AppletClassLoader's ThreadGroup,
458:             * this method should NOT be called from within the AppletClassLoader's
459:             * ThreadGroup.
460:             */
461:            synchronized void release() {
462:                if (usageCount > 1) {
463:                    --usageCount;
464:                } else {
465:                    if (appContext != null) {
466:                        try {
467:                            appContext.dispose(); // nuke the world!
468:                        } catch (IllegalThreadStateException e) {
469:                        }
470:                    }
471:                    usageCount = 0;
472:                    appContext = null;
473:                    threadGroup = null;
474:                }
475:            }
476:
477:            private static AppletMessageHandler mh = new AppletMessageHandler(
478:                    "appletclassloader");
479:
480:            /*
481:             * Prints a class loading error message.
482:             */
483:            private static void printError(String name, Throwable e) {
484:                String s = null;
485:                if (e == null) {
486:                    s = mh.getMessage("filenotfound", name);
487:                } else if (e instanceof  IOException) {
488:                    s = mh.getMessage("fileioexception", name);
489:                } else if (e instanceof  ClassFormatError) {
490:                    s = mh.getMessage("fileformat", name);
491:                } else if (e instanceof  ThreadDeath) {
492:                    s = mh.getMessage("filedeath", name);
493:                } else if (e instanceof  Error) {
494:                    s = mh.getMessage("fileerror", e.toString(), name);
495:                }
496:                if (s != null) {
497:                    System.err.println(s);
498:                }
499:            }
500:        }
501:
502:        /*
503:         * The AppContextCreator class is used to create an AppContext from within
504:         * a Thread belonging to the new AppContext's ThreadGroup.  To wait for
505:         * this operation to complete before continuing, wait for the notifyAll()
506:         * operation on the syncObject to occur.
507:         */
508:        class AppContextCreator extends Thread {
509:            Object syncObject = new Object();
510:            AppContext appContext = null;
511:
512:            AppContextCreator(ThreadGroup group) {
513:                super (group, "AppContextCreator");
514:            }
515:
516:            public void run() {
517:                synchronized (syncObject) {
518:                    appContext = SunToolkit.createNewAppContext();
519:                    syncObject.notifyAll();
520:                }
521:            } // run()
522:        } // class AppContextCreator
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.