1 /* 2 * Copyright (c) 1997, 2009, 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 27 package java.security; 28 29 import java.io.*; 30 import java.lang.RuntimePermission; 31 import java.lang.reflect.*; 32 import java.net.MalformedURLException; 33 import java.net.URL; 34 import java.util.Enumeration; 35 import java.util.Hashtable; 36 import java.util.PropertyPermission; 37 import java.util.StringTokenizer; 38 import java.util.Vector; 39 import java.util.WeakHashMap; 40 import sun.security.jca.GetInstance; 41 import sun.security.util.Debug; 42 import sun.security.util.SecurityConstants; 43 44 /** 45 * A Policy object is responsible for determining whether code executing 46 * in the Java runtime environment has permission to perform a 47 * security-sensitive operation. 48 * 49 * <p> There is only one Policy object installed in the runtime at any 50 * given time. A Policy object can be installed by calling the 51 * <code>setPolicy</code> method. The installed Policy object can be 52 * obtained by calling the <code>getPolicy</code> method. 53 * 54 * <p> If no Policy object has been installed in the runtime, a call to 55 * <code>getPolicy</code> installs an instance of the default Policy 56 * implementation (a default subclass implementation of this abstract class). 57 * The default Policy implementation can be changed by setting the value 58 * of the "policy.provider" security property (in the Java security properties 59 * file) to the fully qualified name of the desired Policy subclass 60 * implementation. The Java security properties file is located in the 61 * file named <JAVA_HOME>/lib/security/java.security. 62 * <JAVA_HOME> refers to the value of the java.home system property, 63 * and specifies the directory where the JRE is installed. 64 * 65 * <p> Application code can directly subclass Policy to provide a custom 66 * implementation. In addition, an instance of a Policy object can be 67 * constructed by invoking one of the <code>getInstance</code> factory methods 68 * with a standard type. The default policy type is "JavaPolicy". 69 * See Appendix A in the <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA"> 70 * Java Cryptography Architecture API Specification & Reference </a> 71 * for a list of standard Policy types. 72 * 73 * <p> Once a Policy instance has been installed (either by default, or by 74 * calling <code>setPolicy</code>), 75 * the Java runtime invokes its <code>implies</code> when it needs to 76 * determine whether executing code (encapsulated in a ProtectionDomain) 77 * can perform SecurityManager-protected operations. How a Policy object 78 * retrieves its policy data is up to the Policy implementation itself. 79 * The policy data may be stored, for example, in a flat ASCII file, 80 * in a serialized binary file of the Policy class, or in a database. 81 * 82 * <p> The <code>refresh</code> method causes the policy object to 83 * refresh/reload its data. This operation is implementation-dependent. 84 * For example, if the policy object stores its data in configuration files, 85 * calling <code>refresh</code> will cause it to re-read the configuration 86 * policy files. If a refresh operation is not supported, this method does 87 * nothing. Note that refreshed policy may not have an effect on classes 88 * in a particular ProtectionDomain. This is dependent on the Policy 89 * provider's implementation of the <code>implies</code> 90 * method and its PermissionCollection caching strategy. 91 * 92 * @author Roland Schemers 93 * @author Gary Ellison 94 * @see java.security.Provider 95 * @see java.security.ProtectionDomain 96 * @see java.security.Permission 97 */ 98 99 public abstract class Policy { 100 101 /** 102 * A read-only empty PermissionCollection instance. 103 * @since 1.6 104 */ 105 public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = 106 new UnsupportedEmptyCollection(); 107 108 /** the system-wide policy. */ 109 private static Policy policy; // package private for AccessControlContext 110 111 private static final Debug debug = Debug.getInstance("policy"); 112 113 // Cache mapping ProtectionDomain.Key to PermissionCollection 114 private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping; 115 116 /** package private for AccessControlContext */ 117 static boolean isSet() 118 { 119 return policy != null; 120 } 121 122 private static void checkPermission(String type) { 123 SecurityManager sm = System.getSecurityManager(); 124 if (sm != null) { 125 sm.checkPermission(new SecurityPermission("createPolicy." + type)); 126 } 127 } 128 129 /** 130 * Returns the installed Policy object. This value should not be cached, 131 * as it may be changed by a call to <code>setPolicy</code>. 132 * This method first calls 133 * <code>SecurityManager.checkPermission</code> with a 134 * <code>SecurityPermission("getPolicy")</code> permission 135 * to ensure it's ok to get the Policy object.. 136 * 137 * @return the installed Policy. 138 * 139 * @throws SecurityException 140 * if a security manager exists and its 141 * <code>checkPermission</code> method doesn't allow 142 * getting the Policy object. 143 * 144 * @see SecurityManager#checkPermission(Permission) 145 * @see #setPolicy(java.security.Policy) 146 */ 147 public static Policy getPolicy() 148 { 149 SecurityManager sm = System.getSecurityManager(); 150 if (sm != null) 151 sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION); 152 return getPolicyNoCheck(); 153 } 154 155 /** 156 * Returns the installed Policy object, skipping the security check. 157 * Used by SecureClassLoader and getPolicy. 158 * 159 * @return the installed Policy. 160 * 161 */ 162 static synchronized Policy getPolicyNoCheck() 163 { 164 if (policy == null) { 165 String policy_class = null; 166 policy_class = AccessController.doPrivileged( 167 new PrivilegedAction<String>() { 168 public String run() { 169 return Security.getProperty("policy.provider"); 170 } 171 }); 172 if (policy_class == null) { 173 policy_class = "sun.security.provider.PolicyFile"; 174 } 175 176 try { 177 policy = (Policy) 178 Class.forName(policy_class).newInstance(); 179 } catch (Exception e) { 180 /* 181 * The policy_class seems to be an extension 182 * so we have to bootstrap loading it via a policy 183 * provider that is on the bootclasspath 184 * If it loads then shift gears to using the configured 185 * provider. 186 */ 187 188 // install the bootstrap provider to avoid recursion 189 policy = new sun.security.provider.PolicyFile(); 190 191 final String pc = policy_class; 192 Policy p = AccessController.doPrivileged( 193 new PrivilegedAction<Policy>() { 194 public Policy run() { 195 try { 196 ClassLoader cl = 197 ClassLoader.getSystemClassLoader(); 198 // we want the extension loader 199 ClassLoader extcl = null; 200 while (cl != null) { 201 extcl = cl; 202 cl = cl.getParent(); 203 } 204 return (extcl != null ? (Policy)Class.forName( 205 pc, true, extcl).newInstance() : null); 206 } catch (Exception e) { 207 if (debug != null) { 208 debug.println("policy provider " + 209 pc + 210 " not available"); 211 e.printStackTrace(); 212 } 213 return null; 214 } 215 } 216 }); 217 /* 218 * if it loaded install it as the policy provider. Otherwise 219 * continue to use the system default implementation 220 */ 221 if (p != null) { 222 policy = p; 223 } else { 224 if (debug != null) { 225 debug.println("using sun.security.provider.PolicyFile"); 226 } 227 } 228 } 229 } 230 return policy; 231 } 232 233 /** 234 * Sets the system-wide Policy object. This method first calls 235 * <code>SecurityManager.checkPermission</code> with a 236 * <code>SecurityPermission("setPolicy")</code> 237 * permission to ensure it's ok to set the Policy. 238 * 239 * @param p the new system Policy object. 240 * 241 * @throws SecurityException 242 * if a security manager exists and its 243 * <code>checkPermission</code> method doesn't allow 244 * setting the Policy. 245 * 246 * @see SecurityManager#checkPermission(Permission) 247 * @see #getPolicy() 248 * 249 */ 250 public static void setPolicy(Policy p) 251 { 252 SecurityManager sm = System.getSecurityManager(); 253 if (sm != null) sm.checkPermission( 254 new SecurityPermission("setPolicy")); 255 if (p != null) { 256 initPolicy(p); 257 } 258 synchronized (Policy.class) { 259 Policy.policy = p; 260 } 261 } 262 263 /** 264 * Initialize superclass state such that a legacy provider can 265 * handle queries for itself. 266 * 267 * @since 1.4 268 */ 269 private static void initPolicy (final Policy p) { 270 /* 271 * A policy provider not on the bootclasspath could trigger 272 * security checks fulfilling a call to either Policy.implies 273 * or Policy.getPermissions. If this does occur the provider 274 * must be able to answer for it's own ProtectionDomain 275 * without triggering additional security checks, otherwise 276 * the policy implementation will end up in an infinite 277 * recursion. 278 * 279 * To mitigate this, the provider can collect it's own 280 * ProtectionDomain and associate a PermissionCollection while 281 * it is being installed. The currently installed policy 282 * provider (if there is one) will handle calls to 283 * Policy.implies or Policy.getPermissions during this 284 * process. 285 * 286 * This Policy superclass caches away the ProtectionDomain and 287 * statically binds permissions so that legacy Policy 288 * implementations will continue to function. 289 */ 290 291 ProtectionDomain policyDomain = 292 AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() { 293 public ProtectionDomain run() { 294 return p.getClass().getProtectionDomain(); 295 } 296 }); 297 298 /* 299 * Collect the permissions granted to this protection domain 300 * so that the provider can be security checked while processing 301 * calls to Policy.implies or Policy.getPermissions. 302 */ 303 PermissionCollection policyPerms = null; 304 synchronized (p) { 305 if (p.pdMapping == null) { 306 p.pdMapping = 307 new WeakHashMap<ProtectionDomain.Key, PermissionCollection>(); 308 } 309 } 310 311 if (policyDomain.getCodeSource() != null) { 312 if (Policy.isSet()) { 313 policyPerms = policy.getPermissions(policyDomain); 314 } 315 316 if (policyPerms == null) { // assume it has all 317 policyPerms = new Permissions(); 318 policyPerms.add(SecurityConstants.ALL_PERMISSION); 319 } 320 321 synchronized (p.pdMapping) { 322 // cache of pd to permissions 323 p.pdMapping.put(policyDomain.key, policyPerms); 324 } 325 } 326 return; 327 } 328 329 330 /** 331 * Returns a Policy object of the specified type. 332 * 333 * <p> This method traverses the list of registered security providers, 334 * starting with the most preferred Provider. 335 * A new Policy object encapsulating the 336 * PolicySpi implementation from the first 337 * Provider that supports the specified type is returned. 338 * 339 * <p> Note that the list of registered providers may be retrieved via 340 * the {@link Security#getProviders() Security.getProviders()} method. 341 * 342 * @param type the specified Policy type. See Appendix A in the 343 * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA"> 344 * Java Cryptography Architecture API Specification & Reference </a> 345 * for a list of standard Policy types. 346 * 347 * @param params parameters for the Policy, which may be null. 348 * 349 * @return the new Policy object. 350 * 351 * @exception SecurityException if the caller does not have permission 352 * to get a Policy instance for the specified type. 353 * 354 * @exception NullPointerException if the specified type is null. 355 * 356 * @exception IllegalArgumentException if the specified parameters 357 * are not understood by the PolicySpi implementation 358 * from the selected Provider. 359 * 360 * @exception NoSuchAlgorithmException if no Provider supports a PolicySpi 361 * implementation for the specified type. 362 * 363 * @see Provider 364 * @since 1.6 365 */ 366 public static Policy getInstance(String type, Policy.Parameters params) 367 throws NoSuchAlgorithmException { 368 369 checkPermission(type); 370 try { 371 GetInstance.Instance instance = GetInstance.getInstance("Policy", 372 PolicySpi.class, 373 type, 374 params); 375 return new PolicyDelegate((PolicySpi)instance.impl, 376 instance.provider, 377 type, 378 params); 379 } catch (NoSuchAlgorithmException nsae) { 380 return handleException(nsae); 381 } 382 } 383 384 /** 385 * Returns a Policy object of the specified type. 386 * 387 * <p> A new Policy object encapsulating the 388 * PolicySpi implementation from the specified provider 389 * is returned. The specified provider must be registered 390 * in the provider list. 391 * 392 * <p> Note that the list of registered providers may be retrieved via 393 * the {@link Security#getProviders() Security.getProviders()} method. 394 * 395 * @param type the specified Policy type. See Appendix A in the 396 * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA"> 397 * Java Cryptography Architecture API Specification & Reference </a> 398 * for a list of standard Policy types. 399 * 400 * @param params parameters for the Policy, which may be null. 401 * 402 * @param provider the provider. 403 * 404 * @return the new Policy object. 405 * 406 * @exception SecurityException if the caller does not have permission 407 * to get a Policy instance for the specified type. 408 * 409 * @exception NullPointerException if the specified type is null. 410 * 411 * @exception IllegalArgumentException if the specified provider 412 * is null or empty, 413 * or if the specified parameters are not understood by 414 * the PolicySpi implementation from the specified provider. 415 * 416 * @exception NoSuchProviderException if the specified provider is not 417 * registered in the security provider list. 418 * 419 * @exception NoSuchAlgorithmException if the specified provider does not 420 * support a PolicySpi implementation for the specified type. 421 * 422 * @see Provider 423 * @since 1.6 424 */ 425 public static Policy getInstance(String type, 426 Policy.Parameters params, 427 String provider) 428 throws NoSuchProviderException, NoSuchAlgorithmException { 429 430 if (provider == null || provider.length() == 0) { 431 throw new IllegalArgumentException("missing provider"); 432 } 433 434 checkPermission(type); 435 try { 436 GetInstance.Instance instance = GetInstance.getInstance("Policy", 437 PolicySpi.class, 438 type, 439 params, 440 provider); 441 return new PolicyDelegate((PolicySpi)instance.impl, 442 instance.provider, 443 type, 444 params); 445 } catch (NoSuchAlgorithmException nsae) { 446 return handleException (nsae); 447 } 448 } 449 450 /** 451 * Returns a Policy object of the specified type. 452 * 453 * <p> A new Policy object encapsulating the 454 * PolicySpi implementation from the specified Provider 455 * object is returned. Note that the specified Provider object 456 * does not have to be registered in the provider list. 457 * 458 * @param type the specified Policy type. See Appendix A in the 459 * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html#AppA"> 460 * Java Cryptography Architecture API Specification & Reference </a> 461 * for a list of standard Policy types. 462 * 463 * @param params parameters for the Policy, which may be null. 464 * 465 * @param provider the Provider. 466 * 467 * @return the new Policy object. 468 * 469 * @exception SecurityException if the caller does not have permission 470 * to get a Policy instance for the specified type. 471 * 472 * @exception NullPointerException if the specified type is null. 473 * 474 * @exception IllegalArgumentException if the specified Provider is null, 475 * or if the specified parameters are not understood by 476 * the PolicySpi implementation from the specified Provider. 477 * 478 * @exception NoSuchAlgorithmException if the specified Provider does not 479 * support a PolicySpi implementation for the specified type. 480 * 481 * @see Provider 482 * @since 1.6 483 */ 484 public static Policy getInstance(String type, 485 Policy.Parameters params, 486 Provider provider) 487 throws NoSuchAlgorithmException { 488 489 if (provider == null) { 490 throw new IllegalArgumentException("missing provider"); 491 } 492 493 checkPermission(type); 494 try { 495 GetInstance.Instance instance = GetInstance.getInstance("Policy", 496 PolicySpi.class, 497 type, 498 params, 499 provider); 500 return new PolicyDelegate((PolicySpi)instance.impl, 501 instance.provider, 502 type, 503 params); 504 } catch (NoSuchAlgorithmException nsae) { 505 return handleException (nsae); 506 } 507 } 508 509 private static Policy handleException(NoSuchAlgorithmException nsae) 510 throws NoSuchAlgorithmException { 511 Throwable cause = nsae.getCause(); 512 if (cause instanceof IllegalArgumentException) { 513 throw (IllegalArgumentException)cause; 514 } 515 throw nsae; 516 } 517 518 /** 519 * Return the Provider of this Policy. 520 * 521 * <p> This Policy instance will only have a Provider if it 522 * was obtained via a call to <code>Policy.getInstance</code>. 523 * Otherwise this method returns null. 524 * 525 * @return the Provider of this Policy, or null. 526 * 527 * @since 1.6 528 */ 529 public Provider getProvider() { 530 return null; 531 } 532 533 /** 534 * Return the type of this Policy. 535 * 536 * <p> This Policy instance will only have a type if it 537 * was obtained via a call to <code>Policy.getInstance</code>. 538 * Otherwise this method returns null. 539 * 540 * @return the type of this Policy, or null. 541 * 542 * @since 1.6 543 */ 544 public String getType() { 545 return null; 546 } 547 548 /** 549 * Return Policy parameters. 550 * 551 * <p> This Policy instance will only have parameters if it 552 * was obtained via a call to <code>Policy.getInstance</code>. 553 * Otherwise this method returns null. 554 * 555 * @return Policy parameters, or null. 556 * 557 * @since 1.6 558 */ 559 public Policy.Parameters getParameters() { 560 return null; 561 } 562 563 /** 564 * Return a PermissionCollection object containing the set of 565 * permissions granted to the specified CodeSource. 566 * 567 * <p> Applications are discouraged from calling this method 568 * since this operation may not be supported by all policy implementations. 569 * Applications should solely rely on the <code>implies</code> method 570 * to perform policy checks. If an application absolutely must call 571 * a getPermissions method, it should call 572 * <code>getPermissions(ProtectionDomain)</code>. 573 * 574 * <p> The default implementation of this method returns 575 * Policy.UNSUPPORTED_EMPTY_COLLECTION. This method can be 576 * overridden if the policy implementation can return a set of 577 * permissions granted to a CodeSource. 578 * 579 * @param codesource the CodeSource to which the returned 580 * PermissionCollection has been granted. 581 * 582 * @return a set of permissions granted to the specified CodeSource. 583 * If this operation is supported, the returned 584 * set of permissions must be a new mutable instance 585 * and it must support heterogeneous Permission types. 586 * If this operation is not supported, 587 * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. 588 */ 589 public PermissionCollection getPermissions(CodeSource codesource) { 590 return Policy.UNSUPPORTED_EMPTY_COLLECTION; 591 } 592 593 /** 594 * Return a PermissionCollection object containing the set of 595 * permissions granted to the specified ProtectionDomain. 596 * 597 * <p> Applications are discouraged from calling this method 598 * since this operation may not be supported by all policy implementations. 599 * Applications should rely on the <code>implies</code> method 600 * to perform policy checks. 601 * 602 * <p> The default implementation of this method first retrieves 603 * the permissions returned via <code>getPermissions(CodeSource)</code> 604 * (the CodeSource is taken from the specified ProtectionDomain), 605 * as well as the permissions located inside the specified ProtectionDomain. 606 * All of these permissions are then combined and returned in a new 607 * PermissionCollection object. If <code>getPermissions(CodeSource)</code> 608 * returns Policy.UNSUPPORTED_EMPTY_COLLECTION, then this method 609 * returns the permissions contained inside the specified ProtectionDomain 610 * in a new PermissionCollection object. 611 * 612 * <p> This method can be overridden if the policy implementation 613 * supports returning a set of permissions granted to a ProtectionDomain. 614 * 615 * @param domain the ProtectionDomain to which the returned 616 * PermissionCollection has been granted. 617 * 618 * @return a set of permissions granted to the specified ProtectionDomain. 619 * If this operation is supported, the returned 620 * set of permissions must be a new mutable instance 621 * and it must support heterogeneous Permission types. 622 * If this operation is not supported, 623 * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. 624 * 625 * @since 1.4 626 */ 627 public PermissionCollection getPermissions(ProtectionDomain domain) { 628 PermissionCollection pc = null; 629 630 if (domain == null) 631 return new Permissions(); 632 633 if (pdMapping == null) { 634 initPolicy(this); 635 } 636 637 synchronized (pdMapping) { 638 pc = pdMapping.get(domain.key); 639 } 640 641 if (pc != null) { 642 Permissions perms = new Permissions(); 643 synchronized (pc) { 644 for (Enumeration<Permission> e = pc.elements() ; e.hasMoreElements() ;) { 645 perms.add(e.nextElement()); 646 } 647 } 648 return perms; 649 } 650 651 pc = getPermissions(domain.getCodeSource()); 652 if (pc == null || pc == UNSUPPORTED_EMPTY_COLLECTION) { 653 pc = new Permissions(); 654 } 655 656 addStaticPerms(pc, domain.getPermissions()); 657 return pc; 658 } 659 660 /** 661 * add static permissions to provided permission collection 662 */ 663 private void addStaticPerms(PermissionCollection perms, 664 PermissionCollection statics) { 665 if (statics != null) { 666 synchronized (statics) { 667 Enumeration<Permission> e = statics.elements(); 668 while (e.hasMoreElements()) { 669 perms.add(e.nextElement()); 670 } 671 } 672 } 673 } 674 675 /** 676 * Evaluates the global policy for the permissions granted to 677 * the ProtectionDomain and tests whether the permission is 678 * granted. 679 * 680 * @param domain the ProtectionDomain to test 681 * @param permission the Permission object to be tested for implication. 682 * 683 * @return true if "permission" is a proper subset of a permission 684 * granted to this ProtectionDomain. 685 * 686 * @see java.security.ProtectionDomain 687 * @since 1.4 688 */ 689 public boolean implies(ProtectionDomain domain, Permission permission) { 690 PermissionCollection pc; 691 692 if (pdMapping == null) { 693 initPolicy(this); 694 } 695 696 synchronized (pdMapping) { 697 pc = pdMapping.get(domain.key); 698 } 699 700 if (pc != null) { 701 return pc.implies(permission); 702 } 703 704 pc = getPermissions(domain); 705 if (pc == null) { 706 return false; 707 } 708 709 synchronized (pdMapping) { 710 // cache it 711 pdMapping.put(domain.key, pc); 712 } 713 714 return pc.implies(permission); 715 } 716 717 /** 718 * Refreshes/reloads the policy configuration. The behavior of this method 719 * depends on the implementation. For example, calling <code>refresh</code> 720 * on a file-based policy will cause the file to be re-read. 721 * 722 * <p> The default implementation of this method does nothing. 723 * This method should be overridden if a refresh operation is supported 724 * by the policy implementation. 725 */ 726 public void refresh() { } 727 728 /** 729 * This subclass is returned by the getInstance calls. All Policy calls 730 * are delegated to the underlying PolicySpi. 731 */ 732 private static class PolicyDelegate extends Policy { 733 734 private PolicySpi spi; 735 private Provider p; 736 private String type; 737 private Policy.Parameters params; 738 739 private PolicyDelegate(PolicySpi spi, Provider p, 740 String type, Policy.Parameters params) { 741 this.spi = spi; 742 this.p = p; 743 this.type = type; 744 this.params = params; 745 } 746 747 @Override public String getType() { return type; } 748 749 @Override public Policy.Parameters getParameters() { return params; } 750 751 @Override public Provider getProvider() { return p; } 752 753 @Override 754 public PermissionCollection getPermissions(CodeSource codesource) { 755 return spi.engineGetPermissions(codesource); 756 } 757 @Override 758 public PermissionCollection getPermissions(ProtectionDomain domain) { 759 return spi.engineGetPermissions(domain); 760 } 761 @Override 762 public boolean implies(ProtectionDomain domain, Permission perm) { 763 return spi.engineImplies(domain, perm); 764 } 765 @Override 766 public void refresh() { 767 spi.engineRefresh(); 768 } 769 } 770 771 /** 772 * This represents a marker interface for Policy parameters. 773 * 774 * @since 1.6 775 */ 776 public static interface Parameters { } 777 778 /** 779 * This class represents a read-only empty PermissionCollection object that 780 * is returned from the <code>getPermissions(CodeSource)</code> and 781 * <code>getPermissions(ProtectionDomain)</code> 782 * methods in the Policy class when those operations are not 783 * supported by the Policy implementation. 784 */ 785 private static class UnsupportedEmptyCollection 786 extends PermissionCollection { 787 788 private Permissions perms; 789 790 /** 791 * Create a read-only empty PermissionCollection object. 792 */ 793 public UnsupportedEmptyCollection() { 794 this.perms = new Permissions(); 795 perms.setReadOnly(); 796 } 797 798 /** 799 * Adds a permission object to the current collection of permission 800 * objects. 801 * 802 * @param permission the Permission object to add. 803 * 804 * @exception SecurityException - if this PermissionCollection object 805 * has been marked readonly 806 */ 807 @Override public void add(Permission permission) { 808 perms.add(permission); 809 } 810 811 /** 812 * Checks to see if the specified permission is implied by the 813 * collection of Permission objects held in this PermissionCollection. 814 * 815 * @param permission the Permission object to compare. 816 * 817 * @return true if "permission" is implied by the permissions in 818 * the collection, false if not. 819 */ 820 @Override public boolean implies(Permission permission) { 821 return perms.implies(permission); 822 } 823 824 /** 825 * Returns an enumeration of all the Permission objects in the 826 * collection. 827 * 828 * @return an enumeration of all the Permissions. 829 */ 830 @Override public Enumeration<Permission> elements() { 831 return perms.elements(); 832 } 833 } 834 }