1 /**
2 * MicroEmulator
3 * Copyright (C) 2006-2007 Bartek Teodorczyk <barteo@barteo.net>
4 * Copyright (C) 2006-2007 Vlad Skarzhevskyy
5 *
6 * It is licensed under the following two licenses as alternatives:
7 * 1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
8 * 2. Apache License (the "AL") Version 2.0
9 *
10 * You may not use this file except in compliance with at least one of
11 * the above two licenses.
12 *
13 * You may obtain a copy of the LGPL at
14 * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
15 *
16 * You may obtain a copy of the AL at
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the LGPL or the AL for the specific language governing permissions and
23 * limitations.
24 *
25 * @version $Id: ExtensionsClassLoader.java 1605 2008-02-25 21:07:14Z barteo $
26 */
27 package org.microemu.app.classloader;
28
29 import java.io.File;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.net.URLClassLoader;
33 import java.security.AccessControlContext;
34 import java.security.AccessController;
35 import java.security.PrivilegedActionException;
36 import java.security.PrivilegedExceptionAction;
37 import java.util.StringTokenizer;
38
39 import org.microemu.app.util.IOUtils;
40 import org.microemu.log.Logger;
41
42 /**
43 *
44 * Class loader for device and other Extensions
45 *
46 * @author vlads
47 *
48 */
49 public class ExtensionsClassLoader extends URLClassLoader {
50
51 private final static boolean debug = false;
52
53 /* The context to be used when loading classes and resources */
54 private AccessControlContext acc;
55
56 public ExtensionsClassLoader(URL[] urls, ClassLoader parent) {
57 super(urls, parent);
58 acc = AccessController.getContext();
59 }
60
61 public void addURL(URL url) {
62 super.addURL(url);
63 }
64
65 public void addClasspath(String classpath) {
66 StringTokenizer st = new StringTokenizer(classpath, ";");
67 while (st.hasMoreTokens()) {
68 try {
69 String path = st.nextToken();
70 if (path.startsWith("file:")) {
71 addURL(new URL(path));
72 } else {
73 addURL(new URL(IOUtils.getCanonicalFileURL(new File(path))));
74 }
75 } catch (MalformedURLException e) {
76 throw new Error(e);
77 }
78 }
79 }
80
81
82 /**
83 * Finds the resource with the given name. A resource is some data (images,
84 * audio, text, etc) that can be accessed by class code in a way that is
85 * independent of the location of the code.
86 *
87 * <p>
88 * The name of a resource is a '<tt>/</tt>'-separated path name that
89 * identifies the resource.
90 *
91 * <p>
92 * Search order is reverse to standard implemenation
93 * </p>
94 *
95 * <p>
96 * This method will first use {@link #findResource(String)} to find the
97 * resource. That failing, this method will NOT invoke the parent class
98 * loader.
99 * </p>
100 *
101 * @param name
102 * The resource name
103 *
104 * @return A <tt>URL</tt> object for reading the resource, or
105 * <tt>null</tt> if the resource could not be found or the invoker
106 * doesn't have adequate privileges to get the resource.
107 *
108 */
109 public URL getResource(final String name) {
110 try {
111 URL url = (URL) AccessController.doPrivileged(new PrivilegedExceptionAction() {
112 public Object run() {
113 return findResource(name);
114 }
115 }, acc);
116 if (url != null) {
117 return url;
118 }
119 } catch (PrivilegedActionException e) {
120 if (debug) {
121 Logger.error("Unable to find resource " + name + " ", e);
122 }
123 }
124 return super.getResource(name);
125 }
126
127 }