KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > ConditionalPermissions


1 /*******************************************************************************
2  * Copyright (c) 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.osgi.framework.internal.core;
12
13 import java.security.Permission JavaDoc;
14 import java.security.PermissionCollection JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.Vector JavaDoc;
17 import org.osgi.framework.FrameworkEvent;
18 import org.osgi.service.condpermadmin.Condition;
19 import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
20
21 /**
22  *
23  * This class manages the Permissions for a given code source. It tracks the
24  * permissions that have yet to be satisfied as well as conditions that are
25  * already satisfied.
26  */

27 public class ConditionalPermissions extends PermissionCollection JavaDoc {
28     private static final long serialVersionUID = 3907215965749000496L;
29     private AbstractBundle bundle;
30     /**
31      * This is the list of satisfiedCPIs that we are waiting to process in bulk
32      * when evaluating the satisfied permissions. Elements are of type
33      * ConditionalPermissionInfoImpl.
34      */

35     private Vector JavaDoc satisfiedCPIs = new Vector JavaDoc();
36     /**
37      * This is set contains that ConditionalPermissionInfos that are satisfied
38      * and immutable.
39      */

40     private ConditionalPermissionSet satisfiedCPS;
41     /**
42      * These are the CPIs that may match this CodeSource. Elements are of type
43      * ConditionalPermissionSet.
44      */

45     private Vector JavaDoc satisfiableCPSs = new Vector JavaDoc();
46     private boolean empty;
47
48     /**
49      * Constructs a ConditionalPermission for the given bundle.
50      *
51      * @param bundle the bundle for which this ConditionalPermission tracks Permissions.
52      */

53     public ConditionalPermissions(AbstractBundle bundle, ConditionalPermissionAdmin cpa) {
54         this.bundle = bundle;
55         satisfiedCPS = new ConditionalPermissionSet(bundle, ConditionalPermissionAdminImpl.EMPTY_COND_PERM_INFO, ConditionalPermissionAdminImpl.EMPTY_COND);
56         Enumeration JavaDoc en = cpa.getConditionalPermissionInfos();
57         while (en.hasMoreElements()) {
58             ConditionalPermissionInfoImpl cpi = (ConditionalPermissionInfoImpl) en.nextElement();
59             checkConditionalPermissionInfo(cpi);
60         }
61     }
62
63     void checkConditionalPermissionInfo(ConditionalPermissionInfoImpl cpi) {
64         try {
65             // first remove the cpi incase of an update
66
removeCPI(cpi);
67             Condition conds[] = cpi.getConditions(bundle);
68             if (conds == null) {
69                 /* Couldn't process the conditions, so we can't use them */
70                 return;
71             }
72             boolean satisfied = true;
73             for (int i = 0; i < conds.length; i++) {
74                 Condition cond = conds[i];
75                 if (cond.isMutable()) {
76                     satisfied = false;
77                 } else if (!cond.isSatisfied()) {// Note: the RFC says if !mutable, evaluated must be true
78
/*
79                      * We can just dump here since we have an immutable and
80                      * unsatisfied condition.
81                      */

82                     return;
83                 } else {
84                     conds[i] = null; /* We can remove satisfied conditions */
85                 }
86             }
87             if (satisfied) {
88                 satisfiedCPIs.add(cpi);
89             } else {
90                 satisfiableCPSs.add(new ConditionalPermissionSet(bundle, new ConditionalPermissionInfoImpl[] {cpi}, conds));
91             }
92         } catch (Exception JavaDoc e) {
93             bundle.framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, e);
94         }
95     }
96
97     private void removeCPI(ConditionalPermissionInfoImpl cpi) {
98         satisfiedCPIs.remove(cpi);
99         satisfiedCPS.remove(cpi);
100         ConditionalPermissionSet cpsArray[] = (ConditionalPermissionSet[]) satisfiableCPSs.toArray(new ConditionalPermissionSet[0]);
101         for (int i = 0; i < cpsArray.length; i++)
102             if (cpsArray[i].remove(cpi))
103                 satisfiableCPSs.remove(cpsArray[i]);
104     }
105
106     /**
107      * This method is not implemented since this PermissionCollection should
108      * only be used by the ConditionalPolicy which never calls this method.
109      *
110      * @see java.security.PermissionCollection#elements()
111      */

112     public void add(Permission JavaDoc perm) {
113         // do nothing
114
}
115
116     public boolean implies(Permission JavaDoc perm) {
117         processPending();
118         boolean newEmpty = !satisfiedCPS.isNonEmpty();
119         if (!newEmpty && satisfiedCPS.implies(perm)) {
120             this.empty = false;
121             return true;
122         }
123         boolean satisfied = false;
124         Vector JavaDoc unevalCondsSets = null;
125         SecurityManager JavaDoc sm = System.getSecurityManager();
126         FrameworkSecurityManager fsm = null;
127         if (sm instanceof FrameworkSecurityManager)
128             fsm = (FrameworkSecurityManager) sm;
129         ConditionalPermissionSet cpsArray[] = (ConditionalPermissionSet[]) satisfiableCPSs.toArray(new ConditionalPermissionSet[0]);
130         cpsLoop: for (int i = 0; i < cpsArray.length; i++) {
131             if (cpsArray[i].isNonEmpty()) {
132                 newEmpty = false;
133                 Condition conds[] = cpsArray[i].getNeededConditions();
134                 if (conds == null)
135                     continue;
136                 // check mutable !isPostponed conditions first;
137
// note that !mutable conditions have already been evaluated
138
for (int j = 0; j < conds.length; j++)
139                     if (conds[j] != null && !conds[j].isPostponed() && !conds[j].isSatisfied())
140                         continue cpsLoop;
141                 // check the implies now
142
if (cpsArray[i].implies(perm)) {
143                     // the permission is implied; the only unevaluated conditions left are mutable postponed conditions
144
// postpone their evaluation until the end
145
Vector JavaDoc unevaluatedConds = null;
146                     for (int j = 0; j < conds.length; j++) {
147                         if (conds[j] != null && conds[j].isPostponed()) {
148                             if (fsm == null) {
149                                 // If there is no FrameworkSecurityManager, we must evaluate now
150
if (!conds[j].isSatisfied())
151                                     continue cpsLoop;
152                             } else {
153                                 if (unevaluatedConds == null)
154                                     unevaluatedConds = new Vector JavaDoc();
155                                 unevaluatedConds.add(conds[j]);
156                             }
157                         }
158                     }
159                     if (unevaluatedConds == null) {
160                         // no postponed conditions exist return true now
161
this.empty = false;
162                         return true;
163                     }
164                     if (unevalCondsSets == null)
165                         unevalCondsSets = new Vector JavaDoc(2);
166                     unevalCondsSets.add(unevaluatedConds.toArray(new Condition[unevaluatedConds.size()]));
167                     satisfied = true;
168                 }
169             } else {
170                 satisfiableCPSs.remove(cpsArray[i]);
171             }
172         }
173         this.empty = newEmpty;
174         if (satisfied && fsm != null) {
175             // There must be at least one set of Conditions to evaluate since
176
// we didn't return right we we realized the permission was satisfied
177
// so unevalCondsSets must be non-null.
178
Condition[][] condArray = (Condition[][]) unevalCondsSets.toArray(new Condition[unevalCondsSets.size()][]);
179             satisfied = fsm.addConditionsForDomain(condArray);
180         }
181         return satisfied;
182     }
183
184     /**
185      * Process any satisfiedCPIs that have been added.
186      */

187     private void processPending() {
188         if (satisfiedCPIs.size() > 0) {
189             synchronized (satisfiedCPIs) {
190                 for (int i = 0; i < satisfiedCPIs.size(); i++) {
191                     ConditionalPermissionInfoImpl cpi = (ConditionalPermissionInfoImpl) satisfiedCPIs.get(i);
192                     if (!cpi.isDeleted())
193                         satisfiedCPS.addConditionalPermissionInfo(cpi);
194                 }
195                 satisfiedCPIs.clear();
196             }
197         }
198     }
199
200     /**
201      * This method is not implemented since this PermissionCollection should
202      * only be used by the ConditionalPolicy which never calls this method.
203      *
204      * @return always returns null.
205      *
206      * @see java.security.PermissionCollection#elements()
207      */

208     public Enumeration JavaDoc elements() {
209         return null;
210     }
211
212     /**
213      * This method returns true if there are no ConditionalPermissionInfos in
214      * this PermissionCollection. The empty condition is only checked during the
215      * implies method, it should only be checked after implies has been called.
216      *
217      * @return false if there are any Conditions that may provide permissions to
218      * this bundle.
219      */

220     boolean isEmpty() {
221         return empty;
222     }
223
224     void unresolvePermissions() {
225         satisfiedCPS.unresolvePermissions();
226         synchronized (satisfiableCPSs) {
227             Enumeration JavaDoc en = satisfiableCPSs.elements();
228             while (en.hasMoreElements()) {
229                 ConditionalPermissionSet cs = (ConditionalPermissionSet) en.nextElement();
230                 cs.unresolvePermissions();
231             }
232         }
233     }
234 }
235
Popular Tags