1 /**
2 * MicroEmulator
3 * Copyright (C) 2006-2007 Bartek Teodorczyk <barteo@barteo.net>
4 * Copyright (C) 2006-2007 Vlad Skarzhevskyy
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * @version $Id: ExtensionsClassLoader.java 1156 2007-04-15 19:56:04Z vlads $
21 */
22 package org.microemu.app.classloader;
23
24 import java.io.File;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.net.URLClassLoader;
28 import java.security.AccessControlContext;
29 import java.security.AccessController;
30 import java.security.PrivilegedActionException;
31 import java.security.PrivilegedExceptionAction;
32 import java.util.StringTokenizer;
33
34 import org.microemu.app.util.IOUtils;
35 import org.microemu.log.Logger;
36
37 /**
38 *
39 * Class loader for device and other Extensions
40 *
41 * @author vlads
42 *
43 */
44 public class ExtensionsClassLoader extends URLClassLoader {
45
46 private final static boolean debug = false;
47
48 /* The context to be used when loading classes and resources */
49 private AccessControlContext acc;
50
51 public ExtensionsClassLoader(URL[] urls, ClassLoader parent) {
52 super(urls, parent);
53 acc = AccessController.getContext();
54 }
55
56 public void addURL(URL url) {
57 super.addURL(url);
58 }
59
60 public void addClasspath(String classpath) {
61 StringTokenizer st = new StringTokenizer(classpath, ";");
62 while (st.hasMoreTokens()) {
63 try {
64 String path = st.nextToken();
65 if (path.startsWith("file:")) {
66 addURL(new URL(path));
67 } else {
68 addURL(new URL(IOUtils.getCanonicalFileURL(new File(path))));
69 }
70 } catch (MalformedURLException e) {
71 throw new Error(e);
72 }
73 }
74 }
75
76
77 /**
78 * Finds the resource with the given name. A resource is some data (images,
79 * audio, text, etc) that can be accessed by class code in a way that is
80 * independent of the location of the code.
81 *
82 * <p>
83 * The name of a resource is a '<tt>/</tt>'-separated path name that
84 * identifies the resource.
85 *
86 * <p>
87 * Search order is reverse to standard implemenation
88 * </p>
89 *
90 * <p>
91 * This method will first use {@link #findResource(String)} to find the
92 * resource. That failing, this method will NOT invoke the parent class
93 * loader.
94 * </p>
95 *
96 * @param name
97 * The resource name
98 *
99 * @return A <tt>URL</tt> object for reading the resource, or
100 * <tt>null</tt> if the resource could not be found or the invoker
101 * doesn't have adequate privileges to get the resource.
102 *
103 */
104 public URL getResource(final String name) {
105 try {
106 URL url = (URL) AccessController.doPrivileged(new PrivilegedExceptionAction() {
107 public Object run() {
108 return findResource(name);
109 }
110 }, acc);
111 if (url != null) {
112 return url;
113 }
114 } catch (PrivilegedActionException e) {
115 if (debug) {
116 Logger.error("Unable to find resource " + name + " ", e);
117 }
118 }
119 return super.getResource(name);
120 }
121
122 }