Showing the changes to java/pkg/sun/misc/Launcher.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,587 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package sun.misc; | ||
| 27 | |||
| 28 | import java.io.File; | ||
| 29 | import java.io.IOException; | ||
| 30 | import java.io.FilePermission; | ||
| 31 | import java.net.URL; | ||
| 32 | import java.net.URLClassLoader; | ||
| 33 | import java.net.MalformedURLException; | ||
| 34 | import java.net.URLStreamHandler; | ||
| 35 | import java.net.URLStreamHandlerFactory; | ||
| 36 | import java.util.HashSet; | ||
| 37 | import java.util.StringTokenizer; | ||
| 38 | import java.util.Set; | ||
| 39 | import java.util.Vector; | ||
| 40 | import java.security.AccessController; | ||
| 41 | import java.security.PrivilegedAction; | ||
| 42 | import java.security.PrivilegedExceptionAction; | ||
| 43 | import java.security.AccessControlContext; | ||
| 44 | import java.security.PermissionCollection; | ||
| 45 | import java.security.Permissions; | ||
| 46 | import java.security.Permission; | ||
| 47 | import java.security.ProtectionDomain; | ||
| 48 | import java.security.CodeSource; | ||
| 49 | import sun.security.util.SecurityConstants; | ||
| 50 | import sun.net.www.ParseUtil; | ||
| 51 | |||
| 52 | /** | ||
| 53 | * This class is used by the system to launch the main application. | ||
| 54 | Launcher */ | ||
| 55 | public class Launcher { | ||
| 56 | private static URLStreamHandlerFactory factory = new Factory(); | ||
| 57 | private static Launcher launcher = new Launcher(); | ||
| 58 | private static String bootClassPath = | ||
| 59 | System.getProperty("sun.boot.class.path"); | ||
| 60 | |||
| 61 | public static Launcher getLauncher() { | ||
| 62 | return launcher; | ||
| 63 | } | ||
| 64 | |||
| 65 | private ClassLoader loader; | ||
| 66 | |||
| 67 | public Launcher() { | ||
| 68 | // Create the extension class loader | ||
| 69 | ClassLoader extcl; | ||
| 70 | try { | ||
| 71 | extcl = ExtClassLoader.getExtClassLoader(); | ||
| 72 | } catch (IOException e) { | ||
| 73 | throw new InternalError( | ||
| 74 | "Could not create extension class loader"); | ||
| 75 | } | ||
| 76 | |||
| 77 | // Now create the class loader to use to launch the application | ||
| 78 | try { | ||
| 79 | loader = AppClassLoader.getAppClassLoader(extcl); | ||
| 80 | } catch (IOException e) { | ||
| 81 | throw new InternalError( | ||
| 82 | "Could not create application class loader"); | ||
| 83 | } | ||
| 84 | |||
| 85 | // Also set the context class loader for the primordial thread. | ||
| 86 | Thread.currentThread().setContextClassLoader(loader); | ||
| 87 | |||
| 88 | // Finally, install a security manager if requested | ||
| 89 | String s = System.getProperty("java.security.manager"); | ||
| 90 | if (s != null) { | ||
| 91 | SecurityManager sm = null; | ||
| 92 | if ("".equals(s) || "default".equals(s)) { | ||
| 93 | sm = new java.lang.SecurityManager(); | ||
| 94 | } else { | ||
| 95 | try { | ||
| 96 | sm = (SecurityManager)loader.loadClass(s).newInstance(); | ||
| 97 | } catch (IllegalAccessException e) { | ||
| 98 | } catch (InstantiationException e) { | ||
| 99 | } catch (ClassNotFoundException e) { | ||
| 100 | } catch (ClassCastException e) { | ||
| 101 | } | ||
| 102 | } | ||
| 103 | if (sm != null) { | ||
| 104 | System.setSecurityManager(sm); | ||
| 105 | } else { | ||
| 106 | throw new InternalError( | ||
| 107 | "Could not create SecurityManager: " + s); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Returns the class loader used to launch the main application. | ||
| 114 | */ | ||
| 115 | public ClassLoader getClassLoader() { | ||
| 116 | return loader; | ||
| 117 | } | ||
| 118 | |||
| 119 | /* | ||
| 120 | * The class loader used for loading installed extensions. | ||
| 121 | */ | ||
| 122 | static class ExtClassLoader extends URLClassLoader { | ||
| 123 | |||
| 124 | static { | ||
| 125 | ClassLoader.registerAsParallelCapable(); | ||
| 126 | } | ||
| 127 | |||
| 128 | /** | ||
| 129 | * create an ExtClassLoader. The ExtClassLoader is created | ||
| 130 | * within a context that limits which files it can read | ||
| 131 | */ | ||
| 132 | public static ExtClassLoader getExtClassLoader() throws IOException | ||
| 133 | { | ||
| 134 | final File[] dirs = getExtDirs(); | ||
| 135 | |||
| 136 | try { | ||
| 137 | // Prior implementations of this doPrivileged() block supplied | ||
| 138 | // aa synthesized ACC via a call to the private method | ||
| 139 | // ExtClassLoader.getContext(). | ||
| 140 | |||
| 141 | return AccessController.doPrivileged( | ||
| 142 | new PrivilegedExceptionAction<ExtClassLoader>() { | ||
| 143 | public ExtClassLoader run() throws IOException { | ||
| 144 | int len = dirs.length; | ||
| 145 | for (int i = 0; i < len; i++) { | ||
| 146 | MetaIndex.registerDirectory(dirs[i]); | ||
| 147 | } | ||
| 148 | return new ExtClassLoader(dirs); | ||
| 149 | } | ||
| 150 | }); | ||
| 151 | } catch (java.security.PrivilegedActionException e) { | ||
| 152 | throw (IOException) e.getException(); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | void addExtURL(URL url) { | ||
| 157 | super.addURL(url); | ||
| 158 | } | ||
| 159 | |||
| 160 | /* | ||
| 161 | * Creates a new ExtClassLoader for the specified directories. | ||
| 162 | */ | ||
| 163 | public ExtClassLoader(File[] dirs) throws IOException { | ||
| 164 | super(getExtURLs(dirs), null, factory); | ||
| 165 | } | ||
| 166 | |||
| 167 | private static File[] getExtDirs() { | ||
| 168 | String s = System.getProperty("java.ext.dirs"); | ||
| 169 | File[] dirs; | ||
| 170 | if (s != null) { | ||
| 171 | StringTokenizer st = | ||
| 172 | new StringTokenizer(s, File.pathSeparator); | ||
| 173 | int count = st.countTokens(); | ||
| 174 | dirs = new File[count]; | ||
| 175 | for (int i = 0; i < count; i++) { | ||
| 176 | dirs[i] = new File(st.nextToken()); | ||
| 177 | } | ||
| 178 | } else { | ||
| 179 | dirs = new File[0]; | ||
| 180 | } | ||
| 181 | return dirs; | ||
| 182 | } | ||
| 183 | |||
| 184 | private static URL[] getExtURLs(File[] dirs) throws IOException { | ||
| 185 | Vector<URL> urls = new Vector<URL>(); | ||
| 186 | for (int i = 0; i < dirs.length; i++) { | ||
| 187 | String[] files = dirs[i].list(); | ||
| 188 | if (files != null) { | ||
| 189 | for (int j = 0; j < files.length; j++) { | ||
| 190 | if (!files[j].equals("meta-index")) { | ||
| 191 | File f = new File(dirs[i], files[j]); | ||
| 192 | urls.add(getFileURL(f)); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | } | ||
| 196 | } | ||
| 197 | URL[] ua = new URL[urls.size()]; | ||
| 198 | urls.copyInto(ua); | ||
| 199 | return ua; | ||
| 200 | } | ||
| 201 | |||
| 202 | /* | ||
| 203 | * Searches the installed extension directories for the specified | ||
| 204 | * library name. For each extension directory, we first look for | ||
| 205 | * the native library in the subdirectory whose name is the value | ||
| 206 | * of the system property <code>os.arch</code>. Failing that, we | ||
| 207 | * look in the extension directory itself. | ||
| 208 | */ | ||
| 209 | public String findLibrary(String name) { | ||
| 210 | name = System.mapLibraryName(name); | ||
| 211 | URL[] urls = super.getURLs(); | ||
| 212 | File prevDir = null; | ||
| 213 | for (int i = 0; i < urls.length; i++) { | ||
| 214 | // Get the ext directory from the URL | ||
| 215 | File dir = new File(urls[i].getPath()).getParentFile(); | ||
| 216 | if (dir != null && !dir.equals(prevDir)) { | ||
| 217 | // Look in architecture-specific subdirectory first | ||
| 218 | // Read from the saved system properties to avoid deadlock | ||
| 219 | String arch = VM.getSavedProperty("os.arch"); | ||
| 220 | if (arch != null) { | ||
| 221 | File file = new File(new File(dir, arch), name); | ||
| 222 | if (file.exists()) { | ||
| 223 | return file.getAbsolutePath(); | ||
| 224 | } | ||
| 225 | } | ||
| 226 | // Then check the extension directory | ||
| 227 | File file = new File(dir, name); | ||
| 228 | if (file.exists()) { | ||
| 229 | return file.getAbsolutePath(); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | prevDir = dir; | ||
| 233 | } | ||
| 234 | return null; | ||
| 235 | } | ||
| 236 | |||
| 237 | private static AccessControlContext getContext(File[] dirs) | ||
| 238 | throws IOException | ||
| 239 | { | ||
| 240 | PathPermissions perms = | ||
| 241 | new PathPermissions(dirs); | ||
| 242 | |||
| 243 | ProtectionDomain domain = new ProtectionDomain( | ||
| 244 | new CodeSource(perms.getCodeBase(), | ||
| 245 | (java.security.cert.Certificate[]) null), | ||
| 246 | perms); | ||
| 247 | |||
| 248 | AccessControlContext acc = | ||
| 249 | new AccessControlContext(new ProtectionDomain[] { domain }); | ||
| 250 | |||
| 251 | return acc; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | /** | ||
| 256 | * The class loader used for loading from java.class.path. | ||
| 257 | * runs in a restricted security context. | ||
| 258 | */ | ||
| 259 | static class AppClassLoader extends URLClassLoader { | ||
| 260 | |||
| 261 | static { | ||
| 262 | ClassLoader.registerAsParallelCapable(); | ||
| 263 | } | ||
| 264 | |||
| 265 | public static ClassLoader getAppClassLoader(final ClassLoader extcl) | ||
| 266 | throws IOException | ||
| 267 | { | ||
| 268 | final String s = System.getProperty("java.class.path"); | ||
| 269 | final File[] path = (s == null) ? new File[0] : getClassPath(s); | ||
| 270 | |||
| 271 | // Note: on bugid 4256530 | ||
| 272 | // Prior implementations of this doPrivileged() block supplied | ||
| 273 | // a rather restrictive ACC via a call to the private method | ||
| 274 | // AppClassLoader.getContext(). This proved overly restrictive | ||
| 275 | // when loading classes. Specifically it prevent | ||
| 276 | // accessClassInPackage.sun.* grants from being honored. | ||
| 277 | // | ||
| 278 | return AccessController.doPrivileged( | ||
| 279 | new PrivilegedAction<AppClassLoader>() { | ||
| 280 | public AppClassLoader run() { | ||
| 281 | URL[] urls = | ||
| 282 | (s == null) ? new URL[0] : pathToURLs(path); | ||
| 283 | return new AppClassLoader(urls, extcl); | ||
| 284 | } | ||
| 285 | }); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* | ||
| 289 | * Creates a new AppClassLoader | ||
| 290 | */ | ||
| 291 | AppClassLoader(URL[] urls, ClassLoader parent) { | ||
| 292 | super(urls, parent, factory); | ||
| 293 | } | ||
| 294 | |||
| 295 | /** | ||
| 296 | * Override loadClass so we can checkPackageAccess. | ||
| 297 | */ | ||
| 298 | public Class loadClass(String name, boolean resolve) | ||
| 299 | throws ClassNotFoundException | ||
| 300 | { | ||
| 301 | int i = name.lastIndexOf('.'); | ||
| 302 | if (i != -1) { | ||
| 303 | SecurityManager sm = System.getSecurityManager(); | ||
| 304 | if (sm != null) { | ||
| 305 | sm.checkPackageAccess(name.substring(0, i)); | ||
| 306 | } | ||
| 307 | } | ||
| 308 | return (super.loadClass(name, resolve)); | ||
| 309 | } | ||
| 310 | |||
| 311 | /** | ||
| 312 | * allow any classes loaded from classpath to exit the VM. | ||
| 313 | */ | ||
| 314 | protected PermissionCollection getPermissions(CodeSource codesource) | ||
| 315 | { | ||
| 316 | PermissionCollection perms = super.getPermissions(codesource); | ||
| 317 | perms.add(new RuntimePermission("exitVM")); | ||
| 318 | return perms; | ||
| 319 | } | ||
| 320 | |||
| 321 | /** | ||
| 322 | * This class loader supports dynamic additions to the class path | ||
| 323 | * at runtime. | ||
| 324 | * | ||
| 325 | * @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch | ||
| 326 | */ | ||
| 327 | private void appendToClassPathForInstrumentation(String path) { | ||
| 328 | assert(Thread.holdsLock(this)); | ||
| 329 | |||
| 330 | // addURL is a no-op if path already contains the URL | ||
| 331 | super.addURL( getFileURL(new File(path)) ); | ||
| 332 | } | ||
| 333 | |||
| 334 | /** | ||
| 335 | * create a context that can read any directories (recursively) | ||
| 336 | * mentioned in the class path. In the case of a jar, it has to | ||
| 337 | * be the directory containing the jar, not just the jar, as jar | ||
| 338 | * files might refer to other jar files. | ||
| 339 | */ | ||
| 340 | |||
| 341 | private static AccessControlContext getContext(File[] cp) | ||
| 342 | throws java.net.MalformedURLException | ||
| 343 | { | ||
| 344 | PathPermissions perms = | ||
| 345 | new PathPermissions(cp); | ||
| 346 | |||
| 347 | ProtectionDomain domain = | ||
| 348 | new ProtectionDomain(new CodeSource(perms.getCodeBase(), | ||
| 349 | (java.security.cert.Certificate[]) null), | ||
| 350 | perms); | ||
| 351 | |||
| 352 | AccessControlContext acc = | ||
| 353 | new AccessControlContext(new ProtectionDomain[] { domain }); | ||
| 354 | |||
| 355 | return acc; | ||
| 356 | } | ||
| 357 | } | ||
| 358 | |||
| 359 | private static class BootClassPathHolder { | ||
| 360 | static final URLClassPath bcp; | ||
| 361 | static { | ||
| 362 | URL[] urls; | ||
| 363 | if (bootClassPath != null) { | ||
| 364 | urls = AccessController.doPrivileged( | ||
| 365 | new PrivilegedAction<URL[]>() { | ||
| 366 | public URL[] run() { | ||
| 367 | File[] classPath = getClassPath(bootClassPath); | ||
| 368 | int len = classPath.length; | ||
| 369 | Set<File> seenDirs = new HashSet<File>(); | ||
| 370 | for (int i = 0; i < len; i++) { | ||
| 371 | File curEntry = classPath[i]; | ||
| 372 | // Negative test used to properly handle | ||
| 373 | // nonexistent jars on boot class path | ||
| 374 | if (!curEntry.isDirectory()) { | ||
| 375 | curEntry = curEntry.getParentFile(); | ||
| 376 | } | ||
| 377 | if (curEntry != null && seenDirs.add(curEntry)) { | ||
| 378 | MetaIndex.registerDirectory(curEntry); | ||
| 379 | } | ||
| 380 | } | ||
| 381 | return pathToURLs(classPath); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | ); | ||
| 385 | } else { | ||
| 386 | urls = new URL[0]; | ||
| 387 | } | ||
| 388 | bcp = new URLClassPath(urls, factory); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | public static URLClassPath getBootstrapClassPath() { | ||
| 393 | return BootClassPathHolder.bcp; | ||
| 394 | } | ||
| 395 | |||
| 396 | private static URL[] pathToURLs(File[] path) { | ||
| 397 | URL[] urls = new URL[path.length]; | ||
| 398 | for (int i = 0; i < path.length; i++) { | ||
| 399 | urls[i] = getFileURL(path[i]); | ||
| 400 | } | ||
| 401 | // DEBUG | ||
| 402 | //for (int i = 0; i < urls.length; i++) { | ||
| 403 | // System.out.println("urls[" + i + "] = " + '"' + urls[i] + '"'); | ||
| 404 | //} | ||
| 405 | return urls; | ||
| 406 | } | ||
| 407 | |||
| 408 | private static File[] getClassPath(String cp) { | ||
| 409 | File[] path; | ||
| 410 | if (cp != null) { | ||
| 411 | int count = 0, maxCount = 1; | ||
| 412 | int pos = 0, lastPos = 0; | ||
| 413 | // Count the number of separators first | ||
| 414 | while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) { | ||
| 415 | maxCount++; | ||
| 416 | lastPos = pos + 1; | ||
| 417 | } | ||
| 418 | path = new File[maxCount]; | ||
| 419 | lastPos = pos = 0; | ||
| 420 | // Now scan for each path component | ||
| 421 | while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) { | ||
| 422 | if (pos - lastPos > 0) { | ||
| 423 | path[count++] = new File(cp.substring(lastPos, pos)); | ||
| 424 | } else { | ||
| 425 | // empty path component translates to "." | ||
| 426 | path[count++] = new File("."); | ||
| 427 | } | ||
| 428 | lastPos = pos + 1; | ||
| 429 | } | ||
| 430 | // Make sure we include the last path component | ||
| 431 | if (lastPos < cp.length()) { | ||
| 432 | path[count++] = new File(cp.substring(lastPos)); | ||
| 433 | } else { | ||
| 434 | path[count++] = new File("."); | ||
| 435 | } | ||
| 436 | // Trim array to correct size | ||
| 437 | if (count != maxCount) { | ||
| 438 | File[] tmp = new File[count]; | ||
| 439 | System.arraycopy(path, 0, tmp, 0, count); | ||
| 440 | path = tmp; | ||
| 441 | } | ||
| 442 | } else { | ||
| 443 | path = new File[0]; | ||
| 444 | } | ||
| 445 | // DEBUG | ||
| 446 | //for (int i = 0; i < path.length; i++) { | ||
| 447 | // System.out.println("path[" + i + "] = " + '"' + path[i] + '"'); | ||
| 448 | //} | ||
| 449 | return path; | ||
| 450 | } | ||
| 451 | |||
| 452 | private static URLStreamHandler fileHandler; | ||
| 453 | |||
| 454 | static URL getFileURL(File file) { | ||
| 455 | try { | ||
| 456 | file = file.getCanonicalFile(); | ||
| 457 | } catch (IOException e) {} | ||
| 458 | |||
| 459 | try { | ||
| 460 | return ParseUtil.fileToEncodedURL(file); | ||
| 461 | } catch (MalformedURLException e) { | ||
| 462 | // Should never happen since we specify the protocol... | ||
| 463 | throw new InternalError(); | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | /* | ||
| 468 | * The stream handler factory for loading system protocol handlers. | ||
| 469 | */ | ||
| 470 | private static class Factory implements URLStreamHandlerFactory { | ||
| 471 | private static String PREFIX = "sun.net.www.protocol"; | ||
| 472 | |||
| 473 | public URLStreamHandler createURLStreamHandler(String protocol) { | ||
| 474 | String name = PREFIX + "." + protocol + ".Handler"; | ||
| 475 | try { | ||
| 476 | Class c = Class.forName(name); | ||
| 477 | return (URLStreamHandler)c.newInstance(); | ||
| 478 | } catch (ClassNotFoundException e) { | ||
| 479 | e.printStackTrace(); | ||
| 480 | } catch (InstantiationException e) { | ||
| 481 | e.printStackTrace(); | ||
| 482 | } catch (IllegalAccessException e) { | ||
| 483 | e.printStackTrace(); | ||
| 484 | } | ||
| 485 | throw new InternalError("could not load " + protocol + | ||
| 486 | "system protocol handler"); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | } | ||
| 490 | |||
| 491 | class PathPermissions extends PermissionCollection { | ||
| 492 | // use serialVersionUID from JDK 1.2.2 for interoperability | ||
| 493 | private static final long serialVersionUID = 8133287259134945693L; | ||
| 494 | |||
| 495 | private File path[]; | ||
| 496 | private Permissions perms; | ||
| 497 | |||
| 498 | URL codeBase; | ||
| 499 | |||
| 500 | PathPermissions(File path[]) | ||
| 501 | { | ||
| 502 | this.path = path; | ||
| 503 | this.perms = null; | ||
| 504 | this.codeBase = null; | ||
| 505 | } | ||
| 506 | |||
| 507 | URL getCodeBase() | ||
| 508 | { | ||
| 509 | return codeBase; | ||
| 510 | } | ||
| 511 | |||
| 512 | public void add(java.security.Permission permission) { | ||
| 513 | throw new SecurityException("attempt to add a permission"); | ||
| 514 | } | ||
| 515 | |||
| 516 | private synchronized void init() | ||
| 517 | { | ||
| 518 | if (perms != null) | ||
| 519 | return; | ||
| 520 | |||
| 521 | perms = new Permissions(); | ||
| 522 | |||
| 523 | // this is needed to be able to create the classloader itself! | ||
| 524 | perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); | ||
| 525 | |||
| 526 | // add permission to read any "java.*" property | ||
| 527 | perms.add(new java.util.PropertyPermission("java.*", | ||
| 528 | SecurityConstants.PROPERTY_READ_ACTION)); | ||
| 529 | |||
| 530 | AccessController.doPrivileged(new PrivilegedAction<Void>() { | ||
| 531 | public Void run() { | ||
| 532 | for (int i=0; i < path.length; i++) { | ||
| 533 | File f = path[i]; | ||
| 534 | String path; | ||
| 535 | try { | ||
| 536 | path = f.getCanonicalPath(); | ||
| 537 | } catch (IOException ioe) { | ||
| 538 | path = f.getAbsolutePath(); | ||
| 539 | } | ||
| 540 | if (i == 0) { | ||
| 541 | codeBase = Launcher.getFileURL(new File(path)); | ||
| 542 | } | ||
| 543 | if (f.isDirectory()) { | ||
| 544 | if (path.endsWith(File.separator)) { | ||
| 545 | perms.add(new FilePermission(path+"-", | ||
| 546 | SecurityConstants.FILE_READ_ACTION)); | ||
| 547 | } else { | ||
| 548 | perms.add(new FilePermission( | ||
| 549 | path + File.separator+"-", | ||
| 550 | SecurityConstants.FILE_READ_ACTION)); | ||
| 551 | } | ||
| 552 | } else { | ||
| 553 | int endIndex = path.lastIndexOf(File.separatorChar); | ||
| 554 | if (endIndex != -1) { | ||
| 555 | path = path.substring(0, endIndex+1) + "-"; | ||
| 556 | perms.add(new FilePermission(path, | ||
| 557 | SecurityConstants.FILE_READ_ACTION)); | ||
| 558 | } else { | ||
| 559 | // XXX? | ||
| 560 | } | ||
| 561 | } | ||
| 562 | } | ||
| 563 | return null; | ||
| 564 | } | ||
| 565 | }); | ||
| 566 | } | ||
| 567 | |||
| 568 | public boolean implies(java.security.Permission permission) { | ||
| 569 | if (perms == null) | ||
| 570 | init(); | ||
| 571 | return perms.implies(permission); | ||
| 572 | } | ||
| 573 | |||
| 574 | public java.util.Enumeration<Permission> elements() { | ||
| 575 | if (perms == null) | ||
| 576 | init(); | ||
| 577 | synchronized (perms) { | ||
| 578 | return perms.elements(); | ||
| 579 | } | ||
| 580 | } | ||
| 581 | |||
| 582 | public String toString() { | ||
| 583 | if (perms == null) | ||
| 584 | init(); | ||
| 585 | return perms.toString(); | ||
| 586 | } | ||
| 587 | } | ||