1 24 package org.riotfamily.common.web.mapping; 25 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import javax.servlet.http.HttpServletRequest ; 33 34 import org.riotfamily.common.web.util.ServletUtils; 35 import org.springframework.beans.BeansException; 36 import org.springframework.context.ApplicationContextException; 37 import org.springframework.util.AntPathMatcher; 38 import org.springframework.util.PathMatcher; 39 import org.springframework.util.StringUtils; 40 import org.springframework.web.servlet.HandlerMapping; 41 42 49 public class AdvancedBeanNameHandlerMapping 50 extends AbstractReverseHandlerMapping { 51 52 private final Map handlerMap = new HashMap (); 53 54 private HashMap patternsByAntPath = new HashMap (); 55 56 private HashMap patternsByBeanName = new HashMap (); 57 58 private PathMatcher pathMatcher = new AntPathMatcher(); 59 60 private boolean stripServletMapping = true; 61 62 private Object rootHandler; 63 64 public void setStripServletMapping(boolean stripServletMapping) { 65 this.stripServletMapping = stripServletMapping; 66 } 67 68 protected boolean isStripServletMapping() { 69 return this.stripServletMapping; 70 } 71 72 77 public void setRootHandler(Object rootHandler) { 78 this.rootHandler = rootHandler; 79 } 80 81 85 protected Object getRootHandler() { 86 return this.rootHandler; 87 } 88 89 92 public void initApplicationContext() throws ApplicationContextException { 93 super.initApplicationContext(); 94 String [] beanNames = getApplicationContext().getBeanDefinitionNames(); 95 96 for (int i = 0; i < beanNames.length; i++) { 98 String [] urls = checkForUrl(beanNames[i]); 99 if (urls.length > 0) { 100 if (logger.isDebugEnabled()) { 101 logger.debug("Found URL mapping [" + beanNames[i] + "]"); 102 } 103 ArrayList patterns = new ArrayList (); 104 for (int j = 0; j < urls.length; j++) { 106 String attributePattern = urls[j]; 107 String antPattern = AttributePattern.convertToAntPattern(attributePattern); 108 registerHandler(antPattern, beanNames[i]); 109 AttributePattern p = new AttributePattern(attributePattern); 110 patternsByAntPath.put(antPattern, p); 111 patterns.add(p); 112 } 113 patternsByBeanName.put(beanNames[i], patterns); 114 } 115 else { 116 if (logger.isDebugEnabled()) { 117 logger.debug("Rejected bean name '" + beanNames[i] + "'"); 118 } 119 } 120 } 121 } 122 123 128 private String [] checkForUrl(String beanName) { 129 List urls = new ArrayList (); 130 if (beanName.startsWith("/")) { 131 urls.add(beanName); 132 } 133 String [] aliases = getApplicationContext().getAliases(beanName); 134 for (int j = 0; j < aliases.length; j++) { 135 if (aliases[j].startsWith("/")) { 136 urls.add(aliases[j]); 137 } 138 } 139 return StringUtils.toStringArray(urls); 140 } 141 142 149 private void registerHandler(String urlPath, Object handler) throws BeansException { 150 Object mappedHandler = this.handlerMap.get(urlPath); 151 if (mappedHandler != null) { 152 throw new ApplicationContextException( 153 "Cannot map handler [" + handler + "] to URL path [" + urlPath + 154 "]: there's already handler [" + mappedHandler + "] mapped"); 155 } 156 157 if (handler instanceof String ) { 159 String handlerName = (String ) handler; 160 if (getApplicationContext().isSingleton(handlerName)) { 161 handler = getApplicationContext().getBean(handlerName); 162 } 163 } 164 165 if (urlPath.equals("/*")) { 166 setDefaultHandler(handler); 167 } 168 else { 169 this.handlerMap.put(urlPath, handler); 170 if (logger.isDebugEnabled()) { 171 logger.debug("Mapped URL path [" + urlPath 172 + "] onto handler [" + handler + "]"); 173 } 174 } 175 } 176 177 protected String getLookupPath(HttpServletRequest request) { 178 if (stripServletMapping) { 179 return ServletUtils.getPathWithoutServletMapping(request); 180 } 181 else { 182 return ServletUtils.getPathWithinApplication(request); 183 } 184 } 185 186 192 public Object getHandlerInternal(HttpServletRequest request) 193 throws Exception { 194 195 String lookupPath = getLookupPath(request); 196 if (logger.isDebugEnabled()) { 197 logger.debug("Looking up handler for [" + lookupPath + "]"); 198 } 199 200 return lookupHandler(lookupPath, request); 201 } 202 203 215 protected Object lookupHandler(String urlPath, HttpServletRequest request) { 216 Object handler = handlerMap.get(urlPath); 218 if (handler == null && "/".equals(urlPath)) { 219 handler = getRootHandler(); 220 } 221 if (handler == null) { 222 String bestMatch = null; 224 for (Iterator it = handlerMap.keySet().iterator(); it.hasNext();) { 225 String path = (String ) it.next(); 226 if (pathMatcher.match(path, urlPath) && 227 (bestMatch == null || bestMatch.length() <= path.length())) { 228 229 bestMatch = path; 230 } 231 } 232 if (bestMatch != null) { 233 exposeAttributes(bestMatch, urlPath, request); 234 exposePathWithinMapping(pathMatcher.extractPathWithinPattern(bestMatch, urlPath), request); 235 handler = handlerMap.get(bestMatch); 236 } 237 } 238 else { 239 exposePathWithinMapping(urlPath, request); 240 } 241 return handler; 242 } 243 244 245 248 protected void exposePathWithinMapping(String pathWithinMapping, HttpServletRequest request) { 249 request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping); 250 } 251 252 protected void exposeAttributes(String antPattern, String urlPath, 253 HttpServletRequest request) { 254 255 AttributePattern pattern = (AttributePattern) patternsByAntPath.get(antPattern); 256 pattern.expose(urlPath, request); 257 258 } 259 260 protected String addServletMappingIfNecessary(String path, 261 HttpServletRequest request) { 262 263 if (path != null && isStripServletMapping()) { 264 return ServletUtils.addServletMapping(path, request); 265 } 266 return path; 267 } 268 269 protected List getPatternsForHandler(String beanName, 270 HttpServletRequest request) { 271 272 return (List ) patternsByBeanName.get(beanName); 273 } 274 275 } 276 | Popular Tags |