OSDN Git Service

2004-08-04 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / libjava / java / security / BasicPermission.java
1 /* BasicPermission.java -- implements a simple named permission
2    Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package java.security;
39
40 import java.io.Serializable;
41 import java.util.Hashtable;
42 import java.util.Enumeration;
43
44 /**
45  * This class implements a simple model for named permissions without an
46  * associated action list.  That is, either the named permission is granted
47  * or it is not.
48  *
49  * <p>It also supports trailing wildcards to allow the easy granting of
50  * permissions in a hierarchical fashion.  (For example, the name "org.gnu.*"
51  * might grant all permissions under the "org.gnu" permissions hierarchy).
52  * The only valid wildcard character is a '*' which matches anything. It
53  * must be the rightmost element in the permission name and must follow a
54  * '.' or else the Permission name must consist of only a '*'. Any other
55  * occurrence of a '*' is not valid.
56  *
57  * <p>This class ignores the action list.  Subclasses can choose to implement
58  * actions on top of this class if desired.
59  *
60  * @author Aaron M. Renn <arenn@urbanophile.com>
61  * @author Eric Blake <ebb9@email.byu.edu>
62  * @see Permission
63  * @see Permissions
64  * @see PermissionCollection
65  * @see RuntimePermission
66  * @see SecurityPermission
67  * @see PropertyPermission
68  * @see AWTPermission
69  * @see NetPermission
70  * @see SecurityManager
71  * @since 1.1
72  * @status updated to 1.4
73  */
74 public abstract class BasicPermission extends Permission
75   implements Serializable
76 {
77   /**
78    * Compatible with JDK 1.1+.
79    */
80   private static final long serialVersionUID = 6279438298436773498L;
81
82   /**
83    * Create a new instance with the specified permission name. If the
84    * name is empty an exception is thrown.
85    *
86    * @param name the name of this permission
87    * @throws NullPointerException if name is null
88    * @throws IllegalArgumentException if name is invalid
89    */
90   public BasicPermission(String name)
91   {
92     super(name);
93
94     // This routine used to check for illegal wildcards, but no such
95     // requirement exists in the specification and Sun's runtime
96     // doesn't appear to do it.
97
98     if ("".equals(name))
99       throw new IllegalArgumentException("Empty name");
100   }
101
102   /**
103    * Create a new instance with the specified permission name. If the name
104    * is empty, or contains an illegal wildcard character, an exception is
105    * thrown. The actions parameter is ignored.
106    *
107    * @param name the name of this permission
108    * @param actions ignored
109    * @throws NullPointerException if name is null
110    * @throws IllegalArgumentException if name is invalid
111    */
112   public BasicPermission(String name, String actions)
113   {
114     this(name);
115   }
116
117   /**
118    * This method tests to see if the specified permission is implied by this
119    * permission.  This will be true if the following conditions are met:<ul>
120    * <li>The specified object is an instance of the same class as this
121    * object.</li>
122    * <li>The name of the specified permission is implied by this permission's
123    * name based on wildcard matching. For example, "a.*" implies "a.b".</li>
124    * </ul>
125    *
126    * @param perm the <code>Permission</code> object to test against
127    * @return true if the specified permission is implied
128    */
129   public boolean implies(Permission perm)
130   {
131     if (! getClass().isInstance(perm))
132       return false;
133
134     String otherName = perm.getName();
135     String name = getName();
136
137     if (name.equals(otherName))
138       return true;
139
140     int last = name.length() - 1;
141     return name.charAt(last) == '*'
142       && otherName.startsWith(name.substring(0, last));
143   }
144
145   /**
146    * This method tests to see if this object is equal to the specified
147    * <code>Object</code>.  This will be true if and only if the specified
148    * object meets the following conditions:<ul>
149    * <li>It is an instance of the same class as this.</li>
150    * <li>It has the same name as this permission.</li>
151    * </ul>
152    *
153    * @param obj the <code>Object</code> to test for equality
154    * @return true if obj is semantically equal to this
155    */
156   public boolean equals(Object obj)
157   {
158     return getClass().isInstance(obj)
159       && getName().equals(((BasicPermission) obj).getName());
160   }
161
162   /**
163    * This method returns a hash code for this permission object.  The hash
164    * code returned is the value returned by calling the <code>hashCode</code>
165    * method on the <code>String</code> that is the name of this permission.
166    *
167    * @return a hash value for this object
168    */
169   public int hashCode()
170   {
171     return getName().hashCode();
172   }
173
174   /**
175    * This method returns a list of the actions associated with this
176    * permission.  This method always returns the empty string ("") since
177    * this class ignores actions.
178    *
179    * @return the action list
180    */
181   public String getActions()
182   {
183     return "";
184   }
185
186   /**
187    * This method returns an instance of <code>PermissionCollection</code>
188    * suitable for storing <code>BasicPermission</code> objects.  The
189    * collection returned can only store objects of the same type as this.
190    * Subclasses which use actions must override this method; but a class with
191    * no actions will work fine with this.
192    *
193    * @return a new empty <code>PermissionCollection</code> object
194    */
195   public PermissionCollection newPermissionCollection()
196   {
197     return new BasicPermissionCollection(getClass());
198   }
199 } // class BasicPermission
200
201 /**
202  * Implements AllPermission.newPermissionCollection, and obeys serialization
203  * of JDK.
204  *
205  * @author Eric Blake <ebb9@email.byu.edu>
206  */
207 final class BasicPermissionCollection extends PermissionCollection
208 {
209   /**
210    * Compatible with JDK 1.1+.
211    */
212   private static final long serialVersionUID = 739301742472979399L;
213
214   /**
215    * The permissions in the collection.
216    *
217    * @serial a hash mapping name to permissions, all of type permClass
218    */
219   private final Hashtable permissions = new Hashtable();
220
221   /**
222    * If "*" is in the collection.
223    *
224    * @serial true if a permission named "*" is in the collection
225    */
226   private boolean all_allowed;
227
228   /**
229    * The runtime class which all entries in the table must belong to.
230    *
231    * @serial the limiting subclass of this collection
232    */
233   private final Class permClass;
234
235   /**
236    * Construct a collection over the given runtime class.
237    *
238    * @param c the class
239    */
240   BasicPermissionCollection(Class c)
241   {
242     permClass = c;
243   }
244
245   /**
246    * Add a Permission. It must be of the same type as the permission which
247    * created this collection.
248    *
249    * @param perm the permission to add
250    * @throws IllegalArgumentException if perm is not the correct type
251    * @throws SecurityException if the collection is read-only
252    */
253   public void add(Permission perm)
254   {
255     if (isReadOnly())
256       throw new SecurityException("readonly");
257     if (! permClass.isInstance(perm))
258       throw new IllegalArgumentException("Expecting instance of " + permClass);
259     BasicPermission bp = (BasicPermission) perm;
260     String name = bp.getName();
261     if (name.equals("*"))
262       all_allowed = true;
263     permissions.put(name, bp);
264   }
265
266   /**
267    * Returns true if this collection implies the given permission.
268    *
269    * @param permission the permission to check
270    * @return true if it is implied by this
271    */
272   public boolean implies(Permission permission)
273   {
274     if (! permClass.isInstance(permission))
275       return false;
276     if (all_allowed)
277       return true;
278     BasicPermission toImply = (BasicPermission) permission;
279     String name = toImply.getName();
280     if (name.equals("*"))
281       return false;
282     int prefixLength = name.length();
283     if (name.endsWith("*"))
284       prefixLength -= 2;
285
286     while (true)
287       {
288         if (permissions.get(name) != null)
289           return true;
290         prefixLength = name.lastIndexOf('.', prefixLength);
291         if (prefixLength < 0)
292           return false;
293         name = name.substring(0, prefixLength + 1) + '*';
294       }
295   }
296
297   /**
298    * Enumerate over the collection.
299    *
300    * @return an enumeration of the collection contents
301    */
302   public Enumeration elements()
303   {
304     return permissions.elements();
305   }
306 } // class BasicPermissionCollection