1 23 24 package javax.security.jacc; 25 26 import java.util.HashMap ; 27 import java.util.ArrayList ; 28 import java.util.BitSet ; 29 import java.util.Collections ; 30 31 38 39 final class HttpMethodSpec { 40 41 private static final String comma = ","; 42 private static final String emptyString = ""; 43 private static final String exclaimationPoint = "!"; 44 45 private static final char exclaimationPointChar = '!'; 46 47 private static Object methodKeys[] = 48 { "DELETE", 49 "GET", 50 "HEAD", 51 "OPTIONS", 52 "POST", 53 "PUT", 54 "TRACE" 55 }; 56 57 private static int mapSize = methodKeys.length; 58 59 private static HashMap methodHash = new HashMap (); 60 static { 61 int b = 1; 62 for (int i=0; i<mapSize; i++) { 63 methodHash.put(methodKeys[i], new Integer (b)); 64 b = b << 1; 65 } 66 }; 67 68 private static int allSet; 69 static { 70 allSet = 0; 71 for (int i=0; i<mapSize; i++) { 72 allSet = allSet << 1; 73 allSet += 1; 74 } 75 } 76 77 private static HttpMethodSpec specArray[] = 78 new HttpMethodSpec [allSet + 1]; 79 static { 80 for (int i=0; i<allSet+1; i++) { 81 specArray[i] = new HttpMethodSpec (false,i); 82 } 83 } 84 85 private static HttpMethodSpec exceptionSpecArray[] = 86 new HttpMethodSpec [allSet + 1]; 87 static { 88 for (int i=0; i<allSet+1; i++) { 89 exceptionSpecArray[i] = new HttpMethodSpec (true,i); 90 } 91 } 92 93 private static HttpMethodSpec allSpec = new HttpMethodSpec (false,0); 94 95 private static ArrayList extensionMethods = new ArrayList (); 96 97 HttpMethodSpec standardSpec; 98 99 boolean exceptionList; 100 int standardMap; 101 BitSet extensionSet; 102 String actions; 103 104 static HttpMethodSpec getSpec (String actions) 105 { 106 HttpMethodSpec rvalue; 107 108 if (actions == null || actions.equals(emptyString)) { 109 rvalue = allSpec; 110 } else { 111 112 BitSet set = new BitSet (); 113 rvalue = getStandardSpec(actions,set); 114 115 if (!set.isEmpty()) { 116 rvalue = new HttpMethodSpec (rvalue,set); 117 } 118 } 119 return rvalue; 120 } 121 122 static HttpMethodSpec getSpec (String [] methods) 123 { 124 HttpMethodSpec rvalue; 125 126 if (methods == null || methods.length == 0) { 127 rvalue = allSpec; 128 } else { 129 130 int map = 0; 131 BitSet set = new BitSet (); 132 133 for (int i=0; i<methods.length; i++) { 134 Integer bit = (Integer ) methodHash.get(methods[i]); 135 if (bit != null) { 136 map |= bit.intValue(); 137 } else { 138 setExtensionBit(methods[i],set); 139 } 140 } 141 142 if (set.isEmpty()) { 143 rvalue = specArray[map]; 144 } else { 145 rvalue = new HttpMethodSpec (specArray[map],set); 146 } 147 } 148 return rvalue; 149 } 150 151 public String toString() { 152 return getActions(); 153 } 154 155 String getActions() 156 { 157 if (standardMap == 0 && extensionSet == null) { 158 return null; 159 } 160 161 synchronized(this) { 162 if (actions != null) { 163 return actions; 164 } 165 166 if (standardSpec != null) { 167 actions = getExtensionActions(standardSpec.getActions(),standardMap, 168 extensionSet); 169 } else { 170 actions = getStandardActions(exceptionList,standardMap); 171 } 172 } 173 174 return actions; 175 } 176 177 public int hashCode() 178 { 179 return (this.exceptionList ? 1 : 0) + (this.standardMap << 1) + 180 ((this.extensionSet == null ? 0 : this.extensionSet.hashCode()) << mapSize +1); 181 } 182 183 public boolean equals (Object that) 184 { 185 boolean rvalue = false; 186 if (that != null && that instanceof HttpMethodSpec ) { 187 if (that == this) { 188 rvalue = true; 189 } else { 190 rvalue = this.hashCode() == ((HttpMethodSpec ) that).hashCode(); 191 } 192 } 193 return rvalue; 194 } 195 196 boolean implies (HttpMethodSpec that) 197 { 198 boolean rvalue; 199 if (this.standardMap == 0 && this.extensionSet == null) { 201 rvalue = true; 202 } 203 else if (that.standardMap == 0 && that.extensionSet == null) { 205 rvalue = false; 206 } 207 else if (this.exceptionList && that.exceptionList) { 209 rvalue = (this.standardMap & that.standardMap) == this.standardMap; 210 if (rvalue) { 211 if (this.extensionSet != null) { 212 if (that.extensionSet == null) { 213 rvalue = false; 214 } else { 215 BitSet clone = (BitSet ) that.extensionSet.clone(); 216 clone.and(this.extensionSet); 217 rvalue = clone.equals(this.extensionSet) ? true : false; 218 } 219 } 220 } 221 } 222 else if (this.exceptionList == that.exceptionList) { 224 rvalue = (this.standardMap & that.standardMap) == that.standardMap; 225 if (rvalue) { 226 if (that.extensionSet != null) { 227 if (this.extensionSet == null) { 228 rvalue = false; 229 } else { 230 BitSet clone = (BitSet ) that.extensionSet.clone(); 231 clone.and(this.extensionSet); 232 rvalue = clone.equals(that.extensionSet); 233 } 234 } 235 } 236 } 237 else if (this.exceptionList) { 239 rvalue = (this.standardMap & that.standardMap) == 0; 240 if (rvalue) { 241 if (that.extensionSet != null) { 242 if (this.extensionSet == null) { 243 rvalue = true; 244 } else { 245 rvalue = this.extensionSet.intersects 246 (that.extensionSet) ? false : true; 247 } 248 } 249 } 250 } 251 else { 253 rvalue = false; 254 } 255 256 return rvalue; 257 } 258 259 261 private HttpMethodSpec (boolean isExceptionList, int map) 262 { 263 standardSpec = null; 264 exceptionList = isExceptionList; 265 standardMap = map; 266 extensionSet = null; 267 actions = null; 268 } 269 270 private HttpMethodSpec(HttpMethodSpec spec, BitSet set) 271 { 272 standardSpec = spec; 273 exceptionList = spec.exceptionList; 274 standardMap = spec.standardMap; 275 extensionSet = set.isEmpty() ? null : set; 276 actions = null; 277 } 278 279 private static void setExtensionBit(String method, BitSet set) { 280 int bitPos; 281 synchronized (extensionMethods) { 282 bitPos = extensionMethods.indexOf(method); 283 if (bitPos < 0) { 284 bitPos = extensionMethods.size(); 285 extensionMethods.add(method); 287 } 288 } 289 set.set(bitPos); 290 } 291 292 private static String getExtensionMethod(int bitPos) 293 { 294 synchronized (extensionMethods) { 295 if (bitPos >= 0 && bitPos < extensionMethods.size()) { 296 return (String ) extensionMethods.get(bitPos); 297 } else { 298 throw new RuntimeException 299 ("invalid (extensionMethods) bit position: '" + bitPos + 300 "' size: '" + extensionMethods.size() + " '"); 301 } 302 } 303 } 304 305 private static HttpMethodSpec getStandardSpec(String actions, BitSet set) 306 { 307 boolean isExceptionList = false; 308 if (actions.charAt(0) == exclaimationPointChar) { 309 isExceptionList = true; 310 if (actions.length() < 2) { 311 throw new IllegalArgumentException 312 ("illegal HTTP method Spec actions: '" + actions + "'"); 313 } 314 actions = actions.substring(1); 315 } 316 317 int map = makeMethodSet(actions, set); 318 319 HttpMethodSpec rvalue; 320 if (isExceptionList) { 321 rvalue = exceptionSpecArray[map]; 322 } else { 323 rvalue = specArray[map]; 324 } 325 326 return rvalue; 327 } 328 329 private static int makeMethodSet (String actions, BitSet set) 330 { 331 int i = 0; 332 int mSet = 0; 333 int commaPos = 0; 334 335 while (commaPos >= 0 && i < actions.length()) { 336 337 commaPos = actions.indexOf(comma,i); 338 339 if (commaPos != 0) { 340 341 String method; 342 if (commaPos < 0) { 343 method = actions.substring(i); 344 } else { 345 method = actions.substring(i,commaPos); 346 } 347 Integer bit = (Integer ) methodHash.get(method); 348 if (bit != null) { 349 mSet |= bit.intValue(); 350 } else { 351 setExtensionBit(method,set); 352 } 353 354 i = commaPos + 1; 355 } 356 357 else { 358 throw new IllegalArgumentException 359 ("illegal HTTP method Spec actions: '" + actions + "'"); 360 } 361 } 362 363 return mSet; 364 } 365 366 private String getExtensionActions(String standardActions, int map, BitSet set) 367 { 368 ArrayList methods = null; 369 for(int i=set.nextSetBit(0); i>=0; i=set.nextSetBit(i+1)) { 370 if (methods == null) { 371 methods = new ArrayList (); 372 } 373 methods.add(getExtensionMethod(i)); 374 } 375 String rvalue; 376 if (methods == null) { 377 rvalue = standardActions; 378 } else { 379 Collections.sort(methods); 380 StringBuffer actBuf = new StringBuffer 381 (standardActions == null ? 382 (exceptionList ? exclaimationPoint : emptyString) : 383 standardActions); 384 for (int i = 0; i < methods.size(); i++) { 385 if (i > 0 || map > 0) { 386 actBuf.append(comma); 387 } 388 actBuf.append(methods.get(i)); 389 } 390 rvalue = actBuf.toString(); 391 } 392 return rvalue; 393 } 394 395 private String getStandardActions(boolean isExceptionList, int map) 396 { 397 int bitValue = 1; 398 399 StringBuffer actBuf = null; 400 401 for (int i=0; i<mapSize; i++) { 402 403 if ((map & bitValue) == bitValue) { 404 if (actBuf == null) { 405 actBuf = new StringBuffer 406 (isExceptionList ? exclaimationPoint : emptyString); 407 } else { 408 actBuf.append(comma); 409 } 410 actBuf.append((String ) methodKeys[i]); 411 } 412 bitValue = bitValue * 2; 413 } 414 415 if (actBuf == null) { 416 return isExceptionList ? exclaimationPoint : emptyString; 417 } else { 418 return actBuf.toString(); 419 } 420 } 421 422 } 423 424 425 426 427 428 429 430 431 | Popular Tags |