ServicePermission.java

00001 /*
00002  * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/ServicePermission.java,v 1.14 2006/06/16 16:31:18 hargrave Exp $
00003  * 
00004  * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
00005  * 
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *      http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 package org.osgi.framework;
00020 
00021 import java.io.IOException;
00022 import java.security.*;
00023 import java.util.Enumeration;
00024 import java.util.Hashtable;
00025 
00042 final public class ServicePermission extends BasicPermission {
00043         static final long                       serialVersionUID        = -7662148639076511574L;
00047         public final static String      GET                                     = "get";
00051         public final static String      REGISTER                        = "register";
00052 
00053         private final static int        ACTION_GET                      = 0x00000001;
00054         private final static int        ACTION_REGISTER         = 0x00000002;
00055         private final static int        ACTION_ALL                      = ACTION_GET
00056                                                                                                                         | ACTION_REGISTER;
00057         private final static int        ACTION_NONE                     = 0;
00061         private transient int           action_mask                     = ACTION_NONE;
00062 
00068         private String                          actions                         = null;
00069 
00100         public ServicePermission(String name, String actions) {
00101                 this(name, getMask(actions));
00102         }
00103 
00110         ServicePermission(String name, int mask) {
00111                 super(name);
00112 
00113                 init(mask);
00114         }
00115 
00121         private void init(int mask) {
00122                 if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
00123                         throw new IllegalArgumentException("invalid action string");
00124                 }
00125 
00126                 action_mask = mask;
00127         }
00128 
00135         private static int getMask(String actions) {
00136                 boolean seencomma = false;
00137 
00138                 int mask = ACTION_NONE;
00139 
00140                 if (actions == null) {
00141                         return mask;
00142                 }
00143 
00144                 char[] a = actions.toCharArray();
00145 
00146                 int i = a.length - 1;
00147                 if (i < 0)
00148                         return mask;
00149 
00150                 while (i != -1) {
00151                         char c;
00152 
00153                         // skip whitespace
00154                         while ((i != -1)
00155                                         && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
00156                                                         || c == '\f' || c == '\t'))
00157                                 i--;
00158 
00159                         // check for the known strings
00160                         int matchlen;
00161 
00162                         if (i >= 2 && (a[i - 2] == 'g' || a[i - 2] == 'G')
00163                                         && (a[i - 1] == 'e' || a[i - 1] == 'E')
00164                                         && (a[i] == 't' || a[i] == 'T')) {
00165                                 matchlen = 3;
00166                                 mask |= ACTION_GET;
00167 
00168                         }
00169                         else
00170                                 if (i >= 7 && (a[i - 7] == 'r' || a[i - 7] == 'R')
00171                                                 && (a[i - 6] == 'e' || a[i - 6] == 'E')
00172                                                 && (a[i - 5] == 'g' || a[i - 5] == 'G')
00173                                                 && (a[i - 4] == 'i' || a[i - 4] == 'I')
00174                                                 && (a[i - 3] == 's' || a[i - 3] == 'S')
00175                                                 && (a[i - 2] == 't' || a[i - 2] == 'T')
00176                                                 && (a[i - 1] == 'e' || a[i - 1] == 'E')
00177                                                 && (a[i] == 'r' || a[i] == 'R')) {
00178                                         matchlen = 8;
00179                                         mask |= ACTION_REGISTER;
00180 
00181                                 }
00182                                 else {
00183                                         // parse error
00184                                         throw new IllegalArgumentException("invalid permission: "
00185                                                         + actions);
00186                                 }
00187 
00188                         // make sure we didn't just match the tail of a word
00189                         // like "ackbarfregister". Also, skip to the comma.
00190                         seencomma = false;
00191                         while (i >= matchlen && !seencomma) {
00192                                 switch (a[i - matchlen]) {
00193                                         case ',' :
00194                                                 seencomma = true;
00195                                         /* FALLTHROUGH */
00196                                         case ' ' :
00197                                         case '\r' :
00198                                         case '\n' :
00199                                         case '\f' :
00200                                         case '\t' :
00201                                                 break;
00202                                         default :
00203                                                 throw new IllegalArgumentException(
00204                                                                 "invalid permission: " + actions);
00205                                 }
00206                                 i--;
00207                         }
00208 
00209                         // point i at the location of the comma minus one (or -1).
00210                         i -= matchlen;
00211                 }
00212 
00213                 if (seencomma) {
00214                         throw new IllegalArgumentException("invalid permission: " + actions);
00215                 }
00216 
00217                 return mask;
00218         }
00219 
00229         public boolean implies(Permission p) {
00230                 if (p instanceof ServicePermission) {
00231                         ServicePermission target = (ServicePermission) p;
00232 
00233                         return (((action_mask & target.action_mask) == target.action_mask) && super
00234                                         .implies(p));
00235                 }
00236 
00237                 return (false);
00238         }
00239 
00247         public String getActions() {
00248                 if (actions == null) {
00249                         StringBuffer sb = new StringBuffer();
00250                         boolean comma = false;
00251 
00252                         if ((action_mask & ACTION_GET) == ACTION_GET) {
00253                                 sb.append(GET);
00254                                 comma = true;
00255                         }
00256 
00257                         if ((action_mask & ACTION_REGISTER) == ACTION_REGISTER) {
00258                                 if (comma)
00259                                         sb.append(',');
00260                                 sb.append(REGISTER);
00261                         }
00262 
00263                         actions = sb.toString();
00264                 }
00265 
00266                 return (actions);
00267         }
00268 
00276         public PermissionCollection newPermissionCollection() {
00277                 return (new ServicePermissionCollection());
00278         }
00279 
00292         public boolean equals(Object obj) {
00293                 if (obj == this) {
00294                         return (true);
00295                 }
00296 
00297                 if (!(obj instanceof ServicePermission)) {
00298                         return (false);
00299                 }
00300 
00301                 ServicePermission p = (ServicePermission) obj;
00302 
00303                 return ((action_mask == p.action_mask) && getName().equals(p.getName()));
00304         }
00305 
00312         public int hashCode() {
00313                 return (getName().hashCode() ^ getActions().hashCode());
00314         }
00315 
00322         int getMask() {
00323                 return (action_mask);
00324         }
00325 
00331         private synchronized void writeObject(java.io.ObjectOutputStream s)
00332                         throws IOException {
00333                 // Write out the actions. The superclass takes care of the name
00334                 // call getActions to make sure actions field is initialized
00335                 if (actions == null)
00336                         getActions();
00337                 s.defaultWriteObject();
00338         }
00339 
00344         private synchronized void readObject(java.io.ObjectInputStream s)
00345                         throws IOException, ClassNotFoundException {
00346                 // Read in the action, then initialize the rest
00347                 s.defaultReadObject();
00348                 init(getMask(actions));
00349         }
00350 }
00351 
00360 final class ServicePermissionCollection extends PermissionCollection {
00361         static final long       serialVersionUID        = 662615640374640621L;
00367         private Hashtable       permissions;
00368 
00374         private boolean         all_allowed;
00375 
00380         public ServicePermissionCollection() {
00381                 permissions = new Hashtable();
00382                 all_allowed = false;
00383         }
00384 
00398         public void add(Permission permission) {
00399                 if (!(permission instanceof ServicePermission))
00400                         throw new IllegalArgumentException("invalid permission: "
00401                                         + permission);
00402                 if (isReadOnly())
00403                         throw new SecurityException("attempt to add a Permission to a "
00404                                         + "readonly PermissionCollection");
00405 
00406                 ServicePermission sp = (ServicePermission) permission;
00407                 String name = sp.getName();
00408 
00409                 ServicePermission existing = (ServicePermission) permissions.get(name);
00410 
00411                 if (existing != null) {
00412                         int oldMask = existing.getMask();
00413                         int newMask = sp.getMask();
00414                         if (oldMask != newMask) {
00415                                 permissions.put(name, new ServicePermission(name, oldMask
00416                                                 | newMask));
00417                         }
00418                 }
00419                 else {
00420                         permissions.put(name, permission);
00421                 }
00422 
00423                 if (!all_allowed) {
00424                         if (name.equals("*"))
00425                                 all_allowed = true;
00426                 }
00427         }
00428 
00440         public boolean implies(Permission permission) {
00441                 if (!(permission instanceof ServicePermission))
00442                         return (false);
00443 
00444                 ServicePermission sp = (ServicePermission) permission;
00445                 ServicePermission x;
00446 
00447                 int desired = sp.getMask();
00448                 int effective = 0;
00449 
00450                 // short circuit if the "*" Permission was added
00451                 if (all_allowed) {
00452                         x = (ServicePermission) permissions.get("*");
00453                         if (x != null) {
00454                                 effective |= x.getMask();
00455                                 if ((effective & desired) == desired)
00456                                         return (true);
00457                         }
00458                 }
00459 
00460                 // strategy:
00461                 // Check for full match first. Then work our way up the
00462                 // name looking for matches on a.b.*
00463 
00464                 String name = sp.getName();
00465 
00466                 x = (ServicePermission) permissions.get(name);
00467 
00468                 if (x != null) {
00469                         // we have a direct hit!
00470                         effective |= x.getMask();
00471                         if ((effective & desired) == desired)
00472                                 return (true);
00473                 }
00474 
00475                 // work our way up the tree...
00476                 int last, offset;
00477 
00478                 offset = name.length() - 1;
00479 
00480                 while ((last = name.lastIndexOf(".", offset)) != -1) {
00481 
00482                         name = name.substring(0, last + 1) + "*";
00483                         x = (ServicePermission) permissions.get(name);
00484 
00485                         if (x != null) {
00486                                 effective |= x.getMask();
00487                                 if ((effective & desired) == desired)
00488                                         return (true);
00489                         }
00490                         offset = last - 1;
00491                 }
00492 
00493                 // we don't have to check for "*" as it was already checked
00494                 // at the top (all_allowed), so we just return false
00495                 return (false);
00496         }
00497 
00505         public Enumeration elements() {
00506                 return (permissions.elements());
00507         }
00508 }

Generated on Mon Jan 11 21:19:16 2010 for OpenMobileIS by  doxygen 1.5.4