BasicPermission.java 9.7 KB

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