KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2003, 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
12 package org.eclipse.osgi.framework.internal.core;
13
14 import java.security.*;
15 import java.util.*;
16 import org.eclipse.osgi.framework.debug.Debug;
17 import org.osgi.framework.Bundle;
18
19 /**
20  * A heterogeneous collection of permissions for a bundle.
21  *
22  */

23 final class BundlePermissions extends BundlePermissionCollection {
24     private static final long serialVersionUID = 3257844389794428984L;
25
26     /**
27      * Maps a Permission's class to an appropriate PermissionCollection.
28      * Class => PermissionCollection
29      */

30     private Hashtable collections = new Hashtable(8); //TODO How dynamic is this?
31

32     /**
33      * Set to an AllPermissionCollection if this Permissions contains AllPermission.
34      */

35     private PermissionCollection allPermission;
36
37     /** Used to load classes for unresolved permissions */
38     private PackageAdminImpl packageAdmin;
39
40     /**
41      * Constructs a new instance of this class.
42      *
43      */

44     BundlePermissions(PackageAdminImpl packageAdmin) {
45         super();
46
47         this.packageAdmin = packageAdmin;
48     }
49
50     /**
51      * Adds the argument to the collection.
52      *
53      * @param permission java.security.Permission
54      * the permission to add to the collection
55      */

56     public void add(Permission permission) {
57         if (isReadOnly()) {
58             throw new SecurityException JavaDoc();
59         }
60
61         PermissionCollection collection;
62
63         synchronized (collections) {
64             collection = findCollection(permission);
65
66             if (collection == null) {
67                 collection = newPermissionCollection(permission);
68             }
69         }
70
71         if (permission instanceof AllPermission) {
72             allPermission = collection;
73         }
74
75         collection.add(permission);
76     }
77
78     /**
79      * Answers an enumeration of the permissions
80      * in the receiver.
81      *
82      * @return Enumeration
83      * the permissions in the receiver.
84      */

85     public Enumeration elements() {
86         return new Enumeration() {
87             Enumeration enumMap = collections.elements();
88             PermissionCollection c;
89             Enumeration enumC;
90             Permission next = findNextPermission();
91
92             public boolean hasMoreElements() {
93                 return (next != null);
94             }
95
96             public Object JavaDoc nextElement() {
97                 if (next == null) {
98                     throw new NoSuchElementException();
99                 } else {
100                     Object JavaDoc answer = next;
101                     next = findNextPermission();
102                     return (answer);
103                 }
104             }
105
106             // This method is the important one. It looks for and
107
// answers the next available permission. If there are
108
// no permissions left to return, it answers null.
109
private Permission findNextPermission() {
110                 // Loop until we get a collection with at least one element.
111
while (c == null && enumMap.hasMoreElements()) {
112                     c = (PermissionCollection) enumMap.nextElement();
113                     enumC = c.elements();
114                     if (!enumC.hasMoreElements())
115                         c = null;
116                 }
117                 // At this point, c == null if there are no more elements,
118
// and otherwise is the first collection with a free element
119
// (with enumC set up to return that element).
120
if (c == null) {
121                     // no more elements, so return null;
122
return (null);
123                 } else {
124                     Permission answer = (Permission) enumC.nextElement();
125                     if (!enumC.hasMoreElements())
126                         c = null;
127                     return (answer);
128                 }
129             }
130         };
131     }
132
133     /**
134      * Find the appropriate permission collection to use for
135      * the given permission.
136      *
137      * @param permission Permission
138      * the permission to find a collection for
139      * @return PermissionCollection
140      * the collection to use with the permission.
141      */

142     private PermissionCollection findCollection(Permission permission) {
143         Class JavaDoc clazz = permission.getClass();
144
145         PermissionCollection collection = (PermissionCollection) collections.get(clazz);
146
147         if (collection == null) {
148             synchronized (collections) {
149                 collection = (PermissionCollection) collections.get(clazz);
150
151                 if (collection == null) {
152                     collection = resolvePermissions(permission);
153                 }
154             }
155         }
156
157         return collection;
158     }
159
160     /**
161      * This method will attempt to resolve unresolved permissions of the
162      * type of the specified permission.
163      *
164      * This method should only be called while holding the collections lock.
165      *
166      * @param permission Permission whose type we shall attempt to resolve.
167      * @return A PermissionCollection for the resolved permissions or
168      * <tt>null</tt> if the permissions cannot currently be resolved.
169      */

170     private PermissionCollection resolvePermissions(Permission permission) {
171         UnresolvedPermissionCollection unresolvedCollection = (UnresolvedPermissionCollection) collections.get(UnresolvedPermission.class);
172
173         if (unresolvedCollection != null) {
174             String JavaDoc name = permission.getClass().getName();
175
176             Vector permissions = unresolvedCollection.getPermissions(name);
177
178             if (permissions != null) {
179                 PermissionCollection collection = null;
180                 Class JavaDoc clazz;
181
182                 // TODO need to evaluate if this still applies with multiple versions of a package
183
// We really need to resolve the permission
184
// by loading it only from the proper classloader,
185
// i.e. the system classloader or and exporting bundle's
186
// classloader. Otherwise there is a security hole.
187
// clazz = packageAdmin.loadServiceClass(name, null);
188
clazz = permission.getClass();
189                 if (clazz == null) {
190                     return null;
191                 }
192
193                 Enumeration permsEnum = permissions.elements();
194
195                 while (permsEnum.hasMoreElements()) {
196                     Permission resolved = ((UnresolvedPermission) permsEnum.nextElement()).resolve(clazz);
197
198                     if (resolved != null) {
199                         if (collection == null) {
200                             collection = newPermissionCollection(resolved);
201                         }
202
203                         collection.add(resolved);
204                     }
205                 }
206
207                 return collection;
208             }
209         }
210
211         return null;
212     }
213
214     /**
215      * Creates a PermissionCollection suitable to hold the specified permission.
216      * The created collection is added to the collections Hashtable.
217      *
218      * This method should only be called while holding the collections lock.
219      */

220     private PermissionCollection newPermissionCollection(Permission permission) {
221         PermissionCollection collection = permission.newPermissionCollection();
222
223         if (collection == null) {
224             collection = new PermissionsHash();
225         }
226
227         collections.put(permission.getClass(), collection);
228
229         return collection;
230     }
231
232     /**
233      * Indicates whether the argument permission is implied
234      * by the permissions contained in the receiver.
235      *
236      * @return boolean
237      * <code>true</code> if the argument permission
238      * is implied by the permissions in the receiver,
239      * and <code>false</code> if it is not.
240      * @param perm java.security.Permission
241      * the permission to check
242      */

243     public boolean implies(Permission perm) {
244         if ((allPermission != null) && allPermission.implies(perm)) {
245             return true;
246         }
247
248         PermissionCollection collection = findCollection(perm);
249
250         if (collection == null) {
251             return false;
252         }
253
254         return collection.implies(perm);
255     }
256
257     /**
258      * The Permission collection will unresolve the permissions in these packages.
259      *
260      * @param refreshedBundles A list of the bundles which have been refreshed
261      * as a result of a packageRefresh
262      */

263     void unresolvePermissions(AbstractBundle[] refreshedBundles) {
264         synchronized (collections) {
265             int size = collections.size();
266
267             Class JavaDoc[] clazzes = new Class JavaDoc[size];
268             Enumeration keysEnum = collections.keys();
269
270             for (int i = 0; i < size; i++) {
271                 clazzes[i] = (Class JavaDoc) keysEnum.nextElement();
272             }
273
274             for (int i = 0; i < size; i++) {
275                 Class JavaDoc clazz = clazzes[i];
276                 Bundle bundle = packageAdmin.getBundle(clazz);
277                 if (bundle == null)
278                     continue;
279                 for (int j = 0; j < refreshedBundles.length; j++)
280                     if (refreshedBundles[j] == bundle) {
281                         if (Debug.DEBUG && Debug.DEBUG_SECURITY) {
282                             Debug.println(" Unresolving permission class " + clazz.getName()); //$NON-NLS-1$
283
}
284                         collections.remove(clazz);
285                         continue;
286                     }
287             }
288         }
289     }
290 }
291
Popular Tags