PackagePermission.java

00001 /*
00002  * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/PackagePermission.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 
00049 public final class PackagePermission extends BasicPermission {
00050         static final long                       serialVersionUID        = -5107705877071099135L;
00054         public final static String      EXPORT                          = "export";
00055 
00059         public final static String      IMPORT                          = "import";
00060 
00061         private final static int        ACTION_EXPORT           = 0x00000001;
00062         private final static int        ACTION_IMPORT           = 0x00000002;
00063         private final static int        ACTION_ALL                      = ACTION_EXPORT
00064                                                                                                                         | ACTION_IMPORT;
00065         private final static int        ACTION_NONE                     = 0;
00069         private transient int           action_mask                     = ACTION_NONE;
00070 
00076         private String                          actions                         = null;
00077 
00106         public PackagePermission(String name, String actions) {
00107                 this(name, getMask(actions));
00108         }
00109 
00116         PackagePermission(String name, int mask) {
00117                 super(name);
00118                 init(mask);
00119         }
00120 
00126         private void init(int mask) {
00127                 if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
00128                         throw new IllegalArgumentException("invalid action string");
00129                 }
00130 
00131                 action_mask = mask;
00132         }
00133 
00140         private static int getMask(String actions) {
00141                 boolean seencomma = false;
00142 
00143                 int mask = ACTION_NONE;
00144 
00145                 if (actions == null) {
00146                         return (mask);
00147                 }
00148 
00149                 char[] a = actions.toCharArray();
00150 
00151                 int i = a.length - 1;
00152                 if (i < 0)
00153                         return (mask);
00154 
00155                 while (i != -1) {
00156                         char c;
00157 
00158                         // skip whitespace
00159                         while ((i != -1)
00160                                         && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
00161                                                         || c == '\f' || c == '\t'))
00162                                 i--;
00163 
00164                         // check for the known strings
00165                         int matchlen;
00166 
00167                         if (i >= 5 && (a[i - 5] == 'i' || a[i - 5] == 'I')
00168                                         && (a[i - 4] == 'm' || a[i - 4] == 'M')
00169                                         && (a[i - 3] == 'p' || a[i - 3] == 'P')
00170                                         && (a[i - 2] == 'o' || a[i - 2] == 'O')
00171                                         && (a[i - 1] == 'r' || a[i - 1] == 'R')
00172                                         && (a[i] == 't' || a[i] == 'T')) {
00173                                 matchlen = 6;
00174                                 mask |= ACTION_IMPORT;
00175 
00176                         }
00177                         else
00178                                 if (i >= 5 && (a[i - 5] == 'e' || a[i - 5] == 'E')
00179                                                 && (a[i - 4] == 'x' || a[i - 4] == 'X')
00180                                                 && (a[i - 3] == 'p' || a[i - 3] == 'P')
00181                                                 && (a[i - 2] == 'o' || a[i - 2] == 'O')
00182                                                 && (a[i - 1] == 'r' || a[i - 1] == 'R')
00183                                                 && (a[i] == 't' || a[i] == 'T')) {
00184                                         matchlen = 6;
00185                                         mask |= ACTION_EXPORT | ACTION_IMPORT;
00186 
00187                                 }
00188                                 else {
00189                                         // parse error
00190                                         throw new IllegalArgumentException("invalid permission: "
00191                                                         + actions);
00192                                 }
00193 
00194                         // make sure we didn't just match the tail of a word
00195                         // like "ackbarfimport". Also, skip to the comma.
00196                         seencomma = false;
00197                         while (i >= matchlen && !seencomma) {
00198                                 switch (a[i - matchlen]) {
00199                                         case ',' :
00200                                                 seencomma = true;
00201                                         /* FALLTHROUGH */
00202                                         case ' ' :
00203                                         case '\r' :
00204                                         case '\n' :
00205                                         case '\f' :
00206                                         case '\t' :
00207                                                 break;
00208                                         default :
00209                                                 throw new IllegalArgumentException(
00210                                                                 "invalid permission: " + actions);
00211                                 }
00212                                 i--;
00213                         }
00214 
00215                         // point i at the location of the comma minus one (or -1).
00216                         i -= matchlen;
00217                 }
00218 
00219                 if (seencomma) {
00220                         throw new IllegalArgumentException("invalid permission: " + actions);
00221                 }
00222 
00223                 return (mask);
00224         }
00225 
00251         public boolean implies(Permission p) {
00252                 if (p instanceof PackagePermission) {
00253                         PackagePermission target = (PackagePermission) p;
00254 
00255                         return (((action_mask & target.action_mask) == target.action_mask) && super
00256                                         .implies(p));
00257                 }
00258 
00259                 return (false);
00260         }
00261 
00274         public String getActions() {
00275                 if (actions == null) {
00276                         StringBuffer sb = new StringBuffer();
00277                         boolean comma = false;
00278 
00279                         if ((action_mask & ACTION_EXPORT) == ACTION_EXPORT) {
00280                                 sb.append(EXPORT);
00281                                 comma = true;
00282                         }
00283 
00284                         if ((action_mask & ACTION_IMPORT) == ACTION_IMPORT) {
00285                                 if (comma)
00286                                         sb.append(',');
00287                                 sb.append(IMPORT);
00288                         }
00289 
00290                         actions = sb.toString();
00291                 }
00292 
00293                 return (actions);
00294         }
00295 
00302         public PermissionCollection newPermissionCollection() {
00303                 return (new PackagePermissionCollection());
00304         }
00305 
00320         public boolean equals(Object obj) {
00321                 if (obj == this) {
00322                         return (true);
00323                 }
00324 
00325                 if (!(obj instanceof PackagePermission)) {
00326                         return (false);
00327                 }
00328 
00329                 PackagePermission p = (PackagePermission) obj;
00330 
00331                 return ((action_mask == p.action_mask) && getName().equals(p.getName()));
00332         }
00333 
00340         public int hashCode() {
00341                 return (getName().hashCode() ^ getActions().hashCode());
00342         }
00343 
00351         int getMask() {
00352                 return (action_mask);
00353         }
00354 
00361         private synchronized void writeObject(java.io.ObjectOutputStream s)
00362                         throws IOException {
00363                 // Write out the actions. The superclass takes care of the name
00364                 // call getActions to make sure actions field is initialized
00365                 if (actions == null)
00366                         getActions();
00367                 s.defaultWriteObject();
00368         }
00369 
00374         private synchronized void readObject(java.io.ObjectInputStream s)
00375                         throws IOException, ClassNotFoundException {
00376                 // Read in the action, then initialize the rest
00377                 s.defaultReadObject();
00378                 init(getMask(actions));
00379         }
00380 }
00381 
00390 final class PackagePermissionCollection extends PermissionCollection {
00391         static final long       serialVersionUID        = -3350758995234427603L;
00397         private Hashtable       permissions;
00398 
00404         private boolean         all_allowed;
00405 
00410         public PackagePermissionCollection() {
00411                 permissions = new Hashtable();
00412                 all_allowed = false;
00413         }
00414 
00429         public void add(Permission permission) {
00430                 if (!(permission instanceof PackagePermission))
00431                         throw new IllegalArgumentException("invalid permission: "
00432                                         + permission);
00433                 if (isReadOnly())
00434                         throw new SecurityException("attempt to add a Permission to a "
00435                                         + "readonly PermissionCollection");
00436 
00437                 PackagePermission pp = (PackagePermission) permission;
00438                 String name = pp.getName();
00439 
00440                 PackagePermission existing = (PackagePermission) permissions.get(name);
00441 
00442                 if (existing != null) {
00443                         int oldMask = existing.getMask();
00444                         int newMask = pp.getMask();
00445                         if (oldMask != newMask) {
00446                                 permissions.put(name, new PackagePermission(name, oldMask
00447                                                 | newMask));
00448 
00449                         }
00450                 }
00451                 else {
00452                         permissions.put(name, permission);
00453                 }
00454 
00455                 if (!all_allowed) {
00456                         if (name.equals("*"))
00457                                 all_allowed = true;
00458                 }
00459         }
00460 
00473         public boolean implies(Permission permission) {
00474                 if (!(permission instanceof PackagePermission))
00475                         return (false);
00476 
00477                 PackagePermission pp = (PackagePermission) permission;
00478                 PackagePermission x;
00479 
00480                 int desired = pp.getMask();
00481                 int effective = 0;
00482 
00483                 // short circuit if the "*" Permission was added
00484                 if (all_allowed) {
00485                         x = (PackagePermission) permissions.get("*");
00486                         if (x != null) {
00487                                 effective |= x.getMask();
00488                                 if ((effective & desired) == desired)
00489                                         return (true);
00490                         }
00491                 }
00492 
00493                 // strategy:
00494                 // Check for full match first. Then work our way up the
00495                 // name looking for matches on a.b.*
00496 
00497                 String name = pp.getName();
00498 
00499                 x = (PackagePermission) permissions.get(name);
00500 
00501                 if (x != null) {
00502                         // we have a direct hit!
00503                         effective |= x.getMask();
00504                         if ((effective & desired) == desired)
00505                                 return (true);
00506                 }
00507 
00508                 // work our way up the tree...
00509                 int last, offset;
00510 
00511                 offset = name.length() - 1;
00512 
00513                 while ((last = name.lastIndexOf(".", offset)) != -1) {
00514 
00515                         name = name.substring(0, last + 1) + "*";
00516                         x = (PackagePermission) permissions.get(name);
00517 
00518                         if (x != null) {
00519                                 effective |= x.getMask();
00520                                 if ((effective & desired) == desired)
00521                                         return (true);
00522                         }
00523                         offset = last - 1;
00524                 }
00525 
00526                 // we don't have to check for "*" as it was already checked
00527                 // at the top (all_allowed), so we just return false
00528                 return (false);
00529         }
00530 
00538         public Enumeration elements() {
00539                 return (permissions.elements());
00540         }
00541 }

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