3131import java .security .SecurityPermission ;
3232import java .security .cert .Certificate ;
3333import java .util .ArrayList ;
34- import java .util .Collections ;
3534import java .util .Enumeration ;
3635import java .util .List ;
3736import java .util .Map ;
3837import java .util .Optional ;
3938import java .util .PropertyPermission ;
4039import java .util .Set ;
4140import java .util .concurrent .ConcurrentHashMap ;
42- import java .util .function .Supplier ;
41+ import java .util .function .Function ;
4342
4443@ SuppressWarnings ("removal" )
4544public class PolicyFile extends java .security .Policy {
@@ -66,16 +65,17 @@ public PolicyFile(URL url) {
6665 }
6766
6867 private PolicyInfo init (URL policy ) throws PolicyInitializationException {
69- PolicyInfo info = new PolicyInfo ();
68+ List < PolicyEntry > entries = new ArrayList <> ();
7069 try (InputStreamReader reader = new InputStreamReader (getInputStream (policy ), StandardCharsets .UTF_8 )) {
7170 List <GrantEntry > grantEntries = PolicyParser .read (reader );
7271 for (GrantEntry grantEntry : grantEntries ) {
73- addGrantEntry (grantEntry , info );
72+ addGrantEntry (grantEntry , entries );
7473 }
7574 } catch (Exception e ) {
7675 throw new PolicyInitializationException ("Failed to load policy from: " + policy , e );
7776 }
78- return info ;
77+
78+ return new PolicyInfo (entries );
7979 }
8080
8181 public static InputStream getInputStream (URL url ) throws IOException {
@@ -98,32 +98,30 @@ private CodeSource getCodeSource(GrantEntry grantEntry) throws PolicyInitializat
9898 }
9999 }
100100
101- private void addGrantEntry (GrantEntry grantEntry , PolicyInfo newInfo ) throws PolicyInitializationException {
101+ private void addGrantEntry (GrantEntry grantEntry , List < PolicyEntry > entries ) throws PolicyInitializationException {
102102 CodeSource codesource = getCodeSource (grantEntry );
103103 if (codesource == null ) {
104104 throw new PolicyInitializationException ("Null CodeSource for: " + grantEntry .codeBase ());
105105 }
106106
107107 List <Permission > permissions = new ArrayList <>();
108- List <PermissionEntry > permissionList = grantEntry .permissionEntries ();
109- for (PermissionEntry pe : permissionList ) {
108+ for (PermissionEntry pe : grantEntry .permissionEntries ()) {
110109 final PermissionEntry expandedEntry = expandPermissionName (pe );
111110 try {
112111 Optional <Permission > perm = getInstance (expandedEntry .permission (), expandedEntry .name (), expandedEntry .action ());
113- if (perm .isPresent ()) {
114- permissions .add (perm .get ());
115- }
112+ perm .ifPresent (permissions ::add );
116113 } catch (ClassNotFoundException e ) {
117114 // these were mostly custom permission classes added for security
118115 // manager. Since security manager is deprecated, we can skip these
119116 // permissions classes.
120117 if (PERM_CLASSES_TO_SKIP .contains (pe .permission ())) {
121- continue ; // skip this permission
118+ continue ;
122119 }
123120 throw new PolicyInitializationException ("Permission class not found: " + pe .permission (), e );
124121 }
125122 }
126- newInfo .policyEntries .add (new PolicyEntry (codesource , permissions ));
123+
124+ entries .add (new PolicyEntry (codesource , permissions ));
127125 }
128126
129127 private static PermissionEntry expandPermissionName (PermissionEntry pe ) {
@@ -188,7 +186,7 @@ public boolean implies(ProtectionDomain pd, Permission p) {
188186 return false ;
189187 }
190188
191- PermissionCollection pc = policyInfo .getOrCompute (pd , () -> getPermissions ( pd ) );
189+ PermissionCollection pc = policyInfo .getOrCompute (pd , this :: getPermissions );
192190 return pc != null && pc .implies (p );
193191 }
194192
@@ -315,18 +313,17 @@ public String toString() {
315313 }
316314
317315 private static class PolicyInfo {
318- final List <PolicyEntry > policyEntries ;
316+ private final List <PolicyEntry > policyEntries ;
319317 private final Map <ProtectionDomain , PermissionCollection > pdMapping ;
320318
321- PolicyInfo () {
322- policyEntries = Collections . synchronizedList ( new ArrayList < PolicyEntry >());
323- pdMapping = new ConcurrentHashMap <>();
319+ PolicyInfo (List < PolicyEntry > entries ) {
320+ this . policyEntries = List . copyOf ( entries ); // an immutable copy for thread safety.
321+ this . pdMapping = new ConcurrentHashMap <>();
324322 }
325323
326- public PermissionCollection getOrCompute (ProtectionDomain pd , Supplier < PermissionCollection > computeFn ) {
327- return pdMapping .computeIfAbsent (pd , k -> computeFn .get ( ));
324+ public PermissionCollection getOrCompute (ProtectionDomain pd , Function < ProtectionDomain , PermissionCollection > computeFn ) {
325+ return pdMapping .computeIfAbsent (pd , k -> computeFn .apply ( k ));
328326 }
329-
330327 }
331328
332329 private static URL newURL (String spec ) throws MalformedURLException , URISyntaxException {
0 commit comments