src/java.base/share/classes/java/security/ProtectionDomain.java
changeset 48207 acfac57f4c35
parent 47216 71c04702a3d5
child 49588 ae568aefc5aa
equal deleted inserted replaced
48206:8b967e200e35 48207:acfac57f4c35
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package java.security;
    26 package java.security;
    27 
    27 
    28 import java.lang.ref.Reference;
       
    29 import java.lang.ref.ReferenceQueue;
       
    30 import java.lang.ref.SoftReference;
       
    31 import java.lang.ref.WeakReference;
       
    32 import java.util.ArrayList;
    28 import java.util.ArrayList;
       
    29 import java.util.Collections;
    33 import java.util.Enumeration;
    30 import java.util.Enumeration;
    34 import java.util.List;
    31 import java.util.List;
       
    32 import java.util.Map;
    35 import java.util.Objects;
    33 import java.util.Objects;
    36 import java.util.concurrent.ConcurrentHashMap;
    34 import java.util.WeakHashMap;
    37 import jdk.internal.misc.JavaSecurityAccess;
    35 import jdk.internal.misc.JavaSecurityAccess;
    38 import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
    36 import jdk.internal.misc.JavaSecurityProtectionDomainAccess;
    39 import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
    37 import static jdk.internal.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache;
    40 import jdk.internal.misc.SharedSecrets;
    38 import jdk.internal.misc.SharedSecrets;
    41 import sun.security.action.GetPropertyAction;
    39 import sun.security.action.GetPropertyAction;
   113             return new AccessControlContext(stack.getContext(), acc).optimize();
   111             return new AccessControlContext(stack.getContext(), acc).optimize();
   114         }
   112         }
   115     }
   113     }
   116 
   114 
   117     static {
   115     static {
   118         // setup SharedSecrets to allow access to doIntersectionPrivilege
   116         // Set up JavaSecurityAccess in SharedSecrets
   119         // methods and ProtectionDomain cache
       
   120         SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl());
   117         SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl());
   121         SharedSecrets.setJavaSecurityProtectionDomainAccess(
   118     }
   122             new JavaSecurityProtectionDomainAccess() {
       
   123                 @Override
       
   124                 public ProtectionDomainCache getProtectionDomainCache() {
       
   125                     return new PDCache();
       
   126                 }
       
   127             });
       
   128     }
       
   129 
       
   130     /**
       
   131      * Used for storing ProtectionDomains as keys in a Map.
       
   132      */
       
   133     static final class Key {}
       
   134 
   119 
   135     /* CodeSource */
   120     /* CodeSource */
   136     private CodeSource codesource ;
   121     private CodeSource codesource ;
   137 
   122 
   138     /* ClassLoader the protection domain was consed from */
   123     /* ClassLoader the protection domain was consed from */
   569 
   554 
   570         return mergedPerms;
   555         return mergedPerms;
   571     }
   556     }
   572 
   557 
   573     /**
   558     /**
   574      * A cache of ProtectionDomains and their Permissions.
   559      * Used for storing ProtectionDomains as keys in a Map.
   575      *
   560      */
   576      * This class stores ProtectionDomains as weak keys in a ConcurrentHashMap
   561     final class Key {}
   577      * with additional support for checking and removing weak keys that are no
   562 
   578      * longer in use. There can be cases where the permission collection may
   563     static {
   579      * have a chain of strong references back to the ProtectionDomain, which
   564         SharedSecrets.setJavaSecurityProtectionDomainAccess(
   580      * ordinarily would prevent the entry from being removed from the map. To
   565             new JavaSecurityProtectionDomainAccess() {
   581      * address that, we wrap the permission collection in a SoftReference so
   566                 public ProtectionDomainCache getProtectionDomainCache() {
   582      * that it can be reclaimed by the garbage collector due to memory demand.
   567                     return new ProtectionDomainCache() {
   583      */
   568                         private final Map<Key, PermissionCollection> map =
   584     private static class PDCache implements ProtectionDomainCache {
   569                             Collections.synchronizedMap
   585         private final ConcurrentHashMap<WeakProtectionDomainKey,
   570                                 (new WeakHashMap<Key, PermissionCollection>());
   586                                         SoftReference<PermissionCollection>>
   571                         public void put(ProtectionDomain pd,
   587                                         pdMap = new ConcurrentHashMap<>();
   572                             PermissionCollection pc) {
   588         private final ReferenceQueue<Key> queue = new ReferenceQueue<>();
   573                             map.put((pd == null ? null : pd.key), pc);
   589 
   574                         }
   590         @Override
   575                         public PermissionCollection get(ProtectionDomain pd) {
   591         public void put(ProtectionDomain pd, PermissionCollection pc) {
   576                             return pd == null ? map.get(null) : map.get(pd.key);
   592             processQueue(queue, pdMap);
   577                         }
   593             WeakProtectionDomainKey weakPd =
   578                     };
   594                 new WeakProtectionDomainKey(pd, queue);
   579                 }
   595             pdMap.put(weakPd, new SoftReference<>(pc));
   580             });
   596         }
       
   597 
       
   598         @Override
       
   599         public PermissionCollection get(ProtectionDomain pd) {
       
   600             processQueue(queue, pdMap);
       
   601             WeakProtectionDomainKey weakPd = new WeakProtectionDomainKey(pd);
       
   602             SoftReference<PermissionCollection> sr = pdMap.get(weakPd);
       
   603             return (sr == null) ? null : sr.get();
       
   604         }
       
   605 
       
   606         /**
       
   607          * Removes weak keys from the map that have been enqueued
       
   608          * on the reference queue and are no longer in use.
       
   609          */
       
   610         private static void processQueue(ReferenceQueue<Key> queue,
       
   611                                          ConcurrentHashMap<? extends
       
   612                                          WeakReference<Key>, ?> pdMap) {
       
   613             Reference<? extends Key> ref;
       
   614             while ((ref = queue.poll()) != null) {
       
   615                 pdMap.remove(ref);
       
   616             }
       
   617         }
       
   618     }
       
   619 
       
   620     /**
       
   621      * A weak key for a ProtectionDomain.
       
   622      */
       
   623     private static class WeakProtectionDomainKey extends WeakReference<Key> {
       
   624         /**
       
   625          * Saved value of the referent's identity hash code, to maintain
       
   626          * a consistent hash code after the referent has been cleared
       
   627          */
       
   628         private final int hash;
       
   629 
       
   630         /**
       
   631          * A key representing a null ProtectionDomain.
       
   632          */
       
   633         private static final Key NULL_KEY = new Key();
       
   634 
       
   635         /**
       
   636          * Create a new WeakProtectionDomain with the specified domain and
       
   637          * registered with a queue.
       
   638          */
       
   639         WeakProtectionDomainKey(ProtectionDomain pd, ReferenceQueue<Key> rq) {
       
   640             this((pd == null ? NULL_KEY : pd.key), rq);
       
   641         }
       
   642 
       
   643         WeakProtectionDomainKey(ProtectionDomain pd) {
       
   644             this(pd == null ? NULL_KEY : pd.key);
       
   645         }
       
   646 
       
   647         private WeakProtectionDomainKey(Key key, ReferenceQueue<Key> rq) {
       
   648             super(key, rq);
       
   649             hash = key.hashCode();
       
   650         }
       
   651 
       
   652         private WeakProtectionDomainKey(Key key) {
       
   653             super(key);
       
   654             hash = key.hashCode();
       
   655         }
       
   656 
       
   657         /**
       
   658          * Returns the identity hash code of the original referent.
       
   659          */
       
   660         @Override
       
   661         public int hashCode() {
       
   662             return hash;
       
   663         }
       
   664 
       
   665         /**
       
   666          * Returns true if the given object is an identical
       
   667          * WeakProtectionDomainKey instance, or, if this object's referent
       
   668          * has not been cleared and the given object is another
       
   669          * WeakProtectionDomainKey instance with an identical non-null
       
   670          * referent as this one.
       
   671          */
       
   672         @Override
       
   673         public boolean equals(Object obj) {
       
   674             if (obj == this) {
       
   675                 return true;
       
   676             }
       
   677 
       
   678             if (obj instanceof WeakProtectionDomainKey) {
       
   679                 Object referent = get();
       
   680                 return (referent != null) &&
       
   681                        (referent == ((WeakProtectionDomainKey)obj).get());
       
   682             } else {
       
   683                 return false;
       
   684             }
       
   685         }
       
   686     }
   581     }
   687 }
   582 }