1 18 19 package org.osgi.service.event; 20 21 import java.io.IOException ; 22 import java.security.Permission ; 23 import java.security.PermissionCollection ; 24 import java.util.Enumeration ; 25 import java.util.Hashtable ; 26 27 45 public final class TopicPermission extends Permission { 46 static final long serialVersionUID = -5855563886961618300L; 47 50 public final static String PUBLISH = "publish"; 54 public final static String SUBSCRIBE = "subscribe"; private final static int ACTION_PUBLISH = 0x00000001; 56 private final static int ACTION_SUBSCRIBE = 0x00000002; 57 private final static int ACTION_ALL = ACTION_PUBLISH 58 | ACTION_SUBSCRIBE; 59 private final static int ACTION_NONE = 0; 60 63 private transient int action_mask = ACTION_NONE; 64 65 68 private transient String prefix; 69 70 75 private String actions = null; 76 77 101 public TopicPermission(String name, String actions) { 102 this(name, getMask(actions)); 103 } 104 105 111 TopicPermission(String name, int mask) { 112 super(name); 113 init(name, mask); 114 } 115 116 122 private void init(String name, int mask) { 123 if ((name == null) || name.length() == 0) { 124 throw new IllegalArgumentException ("invalid name"); } 126 127 if (name.equals("*")) { 128 prefix = ""; 129 } 130 else 131 if (name.endsWith("/*")) { 132 prefix = name.substring(0, name.length() - 1); 133 } 134 else { 135 prefix = null; 136 } 137 138 if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) { 139 throw new IllegalArgumentException ("invalid action string"); } 141 action_mask = mask; 142 } 143 144 150 private static int getMask(String actions) { 151 boolean seencomma = false; 152 int mask = ACTION_NONE; 153 if (actions == null) { 154 return mask; 155 } 156 char[] a = actions.toCharArray(); 157 int i = a.length - 1; 158 if (i < 0) 159 return mask; 160 while (i != -1) { 161 char c; 162 while ((i != -1) 164 && ((c = a[i]) == ' ' || c == '\r' || c == '\n' 165 || c == '\f' || c == '\t')) 166 i--; 167 int matchlen; 169 if (i >= 8 && (a[i - 8] == 's' || a[i - 8] == 'S') 170 && (a[i - 7] == 'u' || a[i - 7] == 'U') 171 && (a[i - 6] == 'b' || a[i - 6] == 'B') 172 && (a[i - 5] == 's' || a[i - 5] == 'S') 173 && (a[i - 4] == 'c' || a[i - 4] == 'C') 174 && (a[i - 3] == 'r' || a[i - 3] == 'R') 175 && (a[i - 2] == 'i' || a[i - 2] == 'I') 176 && (a[i - 1] == 'b' || a[i - 1] == 'B') 177 && (a[i] == 'e' || a[i] == 'E')) { 178 matchlen = 9; 179 mask |= ACTION_SUBSCRIBE; 180 } 181 else 182 if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P') 183 && (a[i - 5] == 'u' || a[i - 5] == 'U') 184 && (a[i - 4] == 'b' || a[i - 4] == 'B') 185 && (a[i - 3] == 'l' || a[i - 3] == 'L') 186 && (a[i - 2] == 'i' || a[i - 2] == 'I') 187 && (a[i - 1] == 's' || a[i - 1] == 'S') 188 && (a[i] == 'h' || a[i] == 'H')) { 189 matchlen = 7; 190 mask |= ACTION_PUBLISH; 191 } 192 else { 193 throw new IllegalArgumentException ("invalid permission: " + actions); 196 } 197 seencomma = false; 200 while (i >= matchlen && !seencomma) { 201 switch (a[i - matchlen]) { 202 case ',' : 203 seencomma = true; 204 205 case ' ' : 206 case '\r' : 207 case '\n' : 208 case '\f' : 209 case '\t' : 210 break; 211 default : 212 throw new IllegalArgumentException ( 213 "invalid permission: " + actions); } 215 i--; 216 } 217 i -= matchlen; 219 } 220 if (seencomma) { 221 throw new IllegalArgumentException ("invalid permission: " + actions); } 223 return mask; 224 } 225 226 246 public boolean implies(Permission p) { 247 if (p instanceof TopicPermission) { 248 TopicPermission target = (TopicPermission) p; 249 if ((action_mask & target.action_mask) == target.action_mask) { 250 if (prefix != null) { 251 return target.getName().startsWith(prefix); 252 } 253 254 return target.getName().equals(getName()); 255 } 256 } 257 return false; 258 } 259 260 271 public String getActions() { 272 if (actions == null) { 273 StringBuffer sb = new StringBuffer (); 274 boolean comma = false; 275 if ((action_mask & ACTION_PUBLISH) == ACTION_PUBLISH) { 276 sb.append(PUBLISH); 277 comma = true; 278 } 279 if ((action_mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) { 280 if (comma) 281 sb.append(','); 282 sb.append(SUBSCRIBE); 283 } 284 actions = sb.toString(); 285 } 286 return actions; 287 } 288 289 295 public PermissionCollection newPermissionCollection() { 296 return new TopicPermissionCollection(); 297 } 298 299 313 public boolean equals(Object obj) { 314 if (obj == this) { 315 return true; 316 } 317 if (!(obj instanceof TopicPermission)) { 318 return false; 319 } 320 TopicPermission p = (TopicPermission) obj; 321 return (action_mask == p.action_mask) && getName().equals(p.getName()); 322 } 323 324 329 public int hashCode() { 330 return getName().hashCode() ^ getActions().hashCode(); 331 } 332 333 340 int getMask() { 341 return action_mask; 342 } 343 344 349 private synchronized void writeObject(java.io.ObjectOutputStream s) 350 throws IOException { 351 if (actions == null) 354 getActions(); 355 s.defaultWriteObject(); 356 } 357 358 362 private synchronized void readObject(java.io.ObjectInputStream s) 363 throws IOException , ClassNotFoundException { 364 s.defaultReadObject(); 366 init(getName(), getMask(actions)); 367 } 368 } 369 370 377 final class TopicPermissionCollection extends PermissionCollection { 378 static final long serialVersionUID = -614647783533924048L; 379 384 private Hashtable permissions; 385 390 private boolean all_allowed; 391 392 396 public TopicPermissionCollection() { 397 permissions = new Hashtable (); 398 all_allowed = false; 399 } 400 401 414 public void add(Permission permission) { 415 if (!(permission instanceof TopicPermission)) 416 throw new IllegalArgumentException ("invalid permission: " + permission); 418 if (isReadOnly()) 419 throw new SecurityException ("attempt to add a Permission to a " + "readonly PermissionCollection"); TopicPermission pp = (TopicPermission) permission; 422 String name = pp.getName(); 423 TopicPermission existing = (TopicPermission) permissions.get(name); 424 if (existing != null) { 425 int oldMask = existing.getMask(); 426 int newMask = pp.getMask(); 427 if (oldMask != newMask) { 428 permissions.put(name, new TopicPermission(name, oldMask 429 | newMask)); 430 } 431 } 432 else { 433 permissions.put(name, permission); 434 } 435 if (!all_allowed) { 436 if (name.equals("*")) all_allowed = true; 438 } 439 } 440 441 452 public boolean implies(Permission permission) { 453 if (!(permission instanceof TopicPermission)) 454 return false; 455 TopicPermission pp = (TopicPermission) permission; 456 TopicPermission x; 457 int desired = pp.getMask(); 458 int effective = 0; 459 if (all_allowed) { 461 x = (TopicPermission) permissions.get("*"); if (x != null) { 463 effective |= x.getMask(); 464 if ((effective & desired) == desired) 465 return true; 466 } 467 } 468 String name = pp.getName(); 472 x = (TopicPermission) permissions.get(name); 473 if (x != null) { 474 effective |= x.getMask(); 476 if ((effective & desired) == desired) 477 return true; 478 } 479 int last, offset; 481 offset = name.length() - 1; 482 while ((last = name.lastIndexOf("/", offset)) != -1) { name = name.substring(0, last + 1) + "*"; x = (TopicPermission) permissions.get(name); 485 if (x != null) { 486 effective |= x.getMask(); 487 if ((effective & desired) == desired) 488 return true; 489 } 490 offset = last - 1; 491 } 492 return false; 495 } 496 497 503 public Enumeration elements() { 504 return permissions.elements(); 505 } 506 } 507 | Popular Tags |