1 9 10 18 package com.atlassian.seraph.util; 19 20 import java.io.Serializable ; 21 import java.util.*; 22 23 49 public class PathMapper implements Serializable 50 { 51 private Map mappings = new HashMap(); 52 private List complexPaths = new ArrayList(); 53 static String [] DEFAULT_KEYS = {"/", "*", "/*"}; 54 55 56 public void put(String key, String pattern) 57 { 58 mappings.put(pattern, key); 59 if (pattern.indexOf('?') > -1 || (pattern.indexOf("*") > -1 && pattern.length() > 1)) 60 { 61 complexPaths.add(pattern); 62 } 63 } 64 65 66 67 public String get(String path) 68 { 69 if (path == null) path = "/"; 70 String mapped = findKey(path, mappings, complexPaths); 71 if (mapped == null) return null; 72 return (String ) mappings.get(mapped); 73 } 74 75 76 77 public Collection getAll(String path) 78 { 79 if (path == null) path = "/"; 80 81 List matches = new ArrayList(); 82 83 String exactKey = findExactKey(path, mappings); 85 86 if (exactKey != null) 87 matches.add(mappings.get(exactKey)); 88 89 for (Iterator iterator = findComplexKeys(path, complexPaths).iterator(); iterator.hasNext();) 91 { 92 String mapped = (String ) iterator.next(); 93 matches.add(mappings.get(mapped)); 94 } 95 96 for (Iterator iterator = findDefaultKeys(mappings).iterator(); iterator.hasNext();) 98 { 99 String mapped = (String ) iterator.next(); 100 matches.add(mappings.get(mapped)); 101 } 102 103 return matches; 104 } 105 106 107 108 private static String findKey(String path, Map mappings, List keys) 109 { 110 String result = findExactKey(path, mappings); 111 if (result == null) result = findComplexKey(path, keys); 112 if (result == null) result = findDefaultKey(mappings); 113 return result; 114 } 115 116 117 118 private static String findExactKey(String path, Map mappings) 119 { 120 if (mappings.containsKey(path)) return path; 121 return null; 122 } 123 124 125 126 private static String findComplexKey(String path, List complexPaths) 127 { 128 int size = complexPaths.size(); 129 for (int i = 0; i < size; i++) 130 { 131 String key = (String ) complexPaths.get(i); 132 if (match(key, path, false)) 133 { 134 return key; 135 } 136 } 137 return null; 138 } 139 140 141 private static Collection findComplexKeys(String path, List complexPaths) 142 { 143 int size = complexPaths.size(); 144 List matches = new ArrayList(); 145 for (int i = 0; i < size; i++) 146 { 147 String key = (String ) complexPaths.get(i); 148 if (match(key, path, false)) 149 { 150 matches.add(key); 151 } 152 } 153 return matches; 154 } 155 156 157 private static String findDefaultKey(Map mappings) 158 { 159 for (int i = 0; i < DEFAULT_KEYS.length; i++) 160 { 161 if (mappings.containsKey(DEFAULT_KEYS[i])) return DEFAULT_KEYS[i]; 162 } 163 return null; 164 } 165 166 167 private static Collection findDefaultKeys(Map mappings) 168 { 169 List matches = new ArrayList(); 170 171 for (int i = 0; i < DEFAULT_KEYS.length; i++) 172 { 173 if (mappings.containsKey(DEFAULT_KEYS[i])) 174 matches.add(DEFAULT_KEYS[i]); 175 } 176 177 return matches; 178 } 179 180 181 private static boolean match(String pattern, String str, boolean isCaseSensitive) 182 { 183 char[] patArr = pattern.toCharArray(); 184 char[] strArr = str.toCharArray(); 185 int patIdxStart = 0; 186 int patIdxEnd = patArr.length - 1; 187 int strIdxStart = 0; 188 int strIdxEnd = strArr.length - 1; 189 char ch; 190 191 boolean containsStar = false; 192 for (int i = 0; i < patArr.length; i++) 193 { 194 if (patArr[i] == '*') 195 { 196 containsStar = true; 197 break; 198 } 199 } 200 201 if (!containsStar) 202 { 203 if (patIdxEnd != strIdxEnd) 205 { 206 return false; } 208 for (int i = 0; i <= patIdxEnd; i++) 209 { 210 ch = patArr[i]; 211 if (ch != '?') 212 { 213 if (isCaseSensitive && ch != strArr[i]) 214 { 215 return false; } 217 if (!isCaseSensitive && Character.toUpperCase(ch) != 218 Character.toUpperCase(strArr[i])) 219 { 220 return false; } 222 } 223 } 224 return true; } 226 227 if (patIdxEnd == 0) 228 { 229 return true; } 231 232 while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) 234 { 235 if (ch != '?') 236 { 237 if (isCaseSensitive && ch != strArr[strIdxStart]) 238 { 239 return false; } 241 if (!isCaseSensitive && Character.toUpperCase(ch) != 242 Character.toUpperCase(strArr[strIdxStart])) 243 { 244 return false; } 246 } 247 patIdxStart++; 248 strIdxStart++; 249 } 250 if (strIdxStart > strIdxEnd) 251 { 252 for (int i = patIdxStart; i <= patIdxEnd; i++) 255 { 256 if (patArr[i] != '*') 257 { 258 return false; 259 } 260 } 261 return true; 262 } 263 264 while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) 266 { 267 if (ch != '?') 268 { 269 if (isCaseSensitive && ch != strArr[strIdxEnd]) 270 { 271 return false; } 273 if (!isCaseSensitive && Character.toUpperCase(ch) != 274 Character.toUpperCase(strArr[strIdxEnd])) 275 { 276 return false; } 278 } 279 patIdxEnd--; 280 strIdxEnd--; 281 } 282 if (strIdxStart > strIdxEnd) 283 { 284 for (int i = patIdxStart; i <= patIdxEnd; i++) 287 { 288 if (patArr[i] != '*') 289 { 290 return false; 291 } 292 } 293 return true; 294 } 295 296 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) 299 { 300 int patIdxTmp = -1; 301 for (int i = patIdxStart + 1; i <= patIdxEnd; i++) 302 { 303 if (patArr[i] == '*') 304 { 305 patIdxTmp = i; 306 break; 307 } 308 } 309 if (patIdxTmp == patIdxStart + 1) 310 { 311 patIdxStart++; 313 continue; 314 } 315 int patLength = (patIdxTmp - patIdxStart - 1); 318 int strLength = (strIdxEnd - strIdxStart + 1); 319 int foundIdx = -1; 320 strLoop: 321 for (int i = 0; i <= strLength - patLength; i++) 322 { 323 for (int j = 0; j < patLength; j++) 324 { 325 ch = patArr[patIdxStart + j + 1]; 326 if (ch != '?') 327 { 328 if (isCaseSensitive && ch != strArr[strIdxStart + i + j]) 329 { 330 continue strLoop; 331 } 332 if (!isCaseSensitive && Character.toUpperCase(ch) != 333 Character.toUpperCase(strArr[strIdxStart + i + j])) 334 { 335 continue strLoop; 336 } 337 } 338 } 339 340 foundIdx = strIdxStart + i; 341 break; 342 } 343 344 if (foundIdx == -1) 345 { 346 return false; 347 } 348 349 patIdxStart = patIdxTmp; 350 strIdxStart = foundIdx + patLength; 351 } 352 353 for (int i = patIdxStart; i <= patIdxEnd; i++) 356 { 357 if (patArr[i] != '*') 358 { 359 return false; 360 } 361 } 362 return true; 363 } 364 365 public String toString() 366 { 367 StringBuffer sb = new StringBuffer (); 368 sb.append("Mappings:\n"); 369 for (Iterator iterator = mappings.keySet().iterator(); iterator.hasNext();) 370 { 371 String key = (String ) iterator.next(); 372 sb.append(key + "=" + (String ) mappings.get(key) + "\n"); 373 } 374 sb.append("Complex Paths:\n"); 375 for (Iterator iterator = complexPaths.iterator(); iterator.hasNext();) 376 { 377 String path = (String ) iterator.next(); 378 sb.append(path + "\n"); 379 } 380 381 return sb.toString(); 382 } 383 } 384 | Popular Tags |