1 9 10 package com.opensymphony.module.sitemesh.mapper; 11 12 import java.util.HashMap ; 13 import java.util.Map ; 14 import java.util.Iterator ; 15 16 42 public final class PathMapper { 43 private Map mappings = new HashMap (); 44 45 46 public void put(String key, String pattern) { 47 if (key != null) { 48 mappings.put(pattern, key); 49 } 50 } 51 52 53 public String get(String path) { 54 if (path == null) path = "/"; 55 String mapped = findKey(path, mappings); 56 if (mapped == null) return null; 57 return (String ) mappings.get(mapped); 58 } 59 60 61 private static String findKey(String path, Map mappings) { 62 String result = findExactKey(path, mappings); 63 if (result == null) result = findComplexKey(path, mappings); 64 if (result == null) result = findDefaultKey(mappings); 65 return result; 66 } 67 68 69 private static String findExactKey(String path, Map mappings) { 70 if (mappings.containsKey(path)) return path; 71 return null; 72 } 73 74 private static String findComplexKey(String path, Map mappings) { 75 Iterator i = mappings.keySet().iterator(); 76 String result = null, key = null; 77 while (i.hasNext()) { 78 key = (String ) i.next(); 79 if (key.length() > 1 && (key.indexOf('?') != -1 || key.indexOf('*') != -1) && match(key, path, false)) { 80 if (result == null || key.length() > result.length()) { 81 result = key; 83 } 84 } 85 } 86 return result; 87 } 88 89 90 private static String findDefaultKey(Map mappings) { 91 String [] defaultKeys = {"/", "*", "/*"}; 92 for (int i = 0; i < defaultKeys.length; i++) { 93 if (mappings.containsKey(defaultKeys[i])) return defaultKeys[i]; 94 } 95 return null; 96 } 97 98 private static boolean match(String pattern, String str, boolean isCaseSensitive) { 99 char[] patArr = pattern.toCharArray(); 100 char[] strArr = str.toCharArray(); 101 int patIdxStart = 0; 102 int patIdxEnd = patArr.length - 1; 103 int strIdxStart = 0; 104 int strIdxEnd = strArr.length - 1; 105 char ch; 106 107 boolean containsStar = false; 108 for (int i = 0; i < patArr.length; i++) { 109 if (patArr[i] == '*') { 110 containsStar = true; 111 break; 112 } 113 } 114 115 if (!containsStar) { 116 if (patIdxEnd != strIdxEnd) { 118 return false; } 120 for (int i = 0; i <= patIdxEnd; i++) { 121 ch = patArr[i]; 122 if (ch != '?') { 123 if (isCaseSensitive && ch != strArr[i]) { 124 return false; } 126 if (!isCaseSensitive && Character.toUpperCase(ch) != 127 Character.toUpperCase(strArr[i])) { 128 return false; } 130 } 131 } 132 return true; } 134 135 if (patIdxEnd == 0) { 136 return true; } 138 139 while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) { 141 if (ch != '?') { 142 if (isCaseSensitive && ch != strArr[strIdxStart]) { 143 return false; } 145 if (!isCaseSensitive && Character.toUpperCase(ch) != 146 Character.toUpperCase(strArr[strIdxStart])) { 147 return false; } 149 } 150 patIdxStart++; 151 strIdxStart++; 152 } 153 if (strIdxStart > strIdxEnd) { 154 for (int i = patIdxStart; i <= patIdxEnd; i++) { 157 if (patArr[i] != '*') { 158 return false; 159 } 160 } 161 return true; 162 } 163 164 while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) { 166 if (ch != '?') { 167 if (isCaseSensitive && ch != strArr[strIdxEnd]) { 168 return false; } 170 if (!isCaseSensitive && Character.toUpperCase(ch) != 171 Character.toUpperCase(strArr[strIdxEnd])) { 172 return false; } 174 } 175 patIdxEnd--; 176 strIdxEnd--; 177 } 178 if (strIdxStart > strIdxEnd) { 179 for (int i = patIdxStart; i <= patIdxEnd; i++) { 182 if (patArr[i] != '*') { 183 return false; 184 } 185 } 186 return true; 187 } 188 189 while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) { 192 int patIdxTmp = -1; 193 for (int i = patIdxStart + 1; i <= patIdxEnd; i++) { 194 if (patArr[i] == '*') { 195 patIdxTmp = i; 196 break; 197 } 198 } 199 if (patIdxTmp == patIdxStart + 1) { 200 patIdxStart++; 202 continue; 203 } 204 int patLength = (patIdxTmp - patIdxStart - 1); 207 int strLength = (strIdxEnd - strIdxStart + 1); 208 int foundIdx = -1; 209 strLoop: 210 for (int i = 0; i <= strLength - patLength; i++) { 211 for (int j = 0; j < patLength; j++) { 212 ch = patArr[patIdxStart + j + 1]; 213 if (ch != '?') { 214 if (isCaseSensitive && ch != strArr[strIdxStart + i + j]) { 215 continue strLoop; 216 } 217 if (!isCaseSensitive && Character.toUpperCase(ch) != 218 Character.toUpperCase(strArr[strIdxStart + i + j])) { 219 continue strLoop; 220 } 221 } 222 } 223 224 foundIdx = strIdxStart + i; 225 break; 226 } 227 228 if (foundIdx == -1) { 229 return false; 230 } 231 232 patIdxStart = patIdxTmp; 233 strIdxStart = foundIdx + patLength; 234 } 235 236 for (int i = patIdxStart; i <= patIdxEnd; i++) { 239 if (patArr[i] != '*') { 240 return false; 241 } 242 } 243 return true; 244 } 245 } | Popular Tags |