History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/security/Policy.java (1 of 18352 files). Show all

Unified · Split

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