/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springmodules.web.servlet.mvc;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.mvc.AbstractUrlViewController;
import org.springframework.web.util.UrlPathHelper;
/**
* Modified {@link org.springframework.web.servlet.mvc.UrlFilenameViewController} for preserving full view path.<br>
* For example, given the path "/foo/index.html", this controller will point to the view "foo/index".
*
* @author The Spring Team
* @author Sergio Bossa
*/
public class FullPathUrlFilenameViewController extends AbstractUrlViewController {
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private String prefix = "";
private String suffix = "";
/** Request URL path String --> view name String */
private final Map viewNameCache = Collections.synchronizedMap(new HashMap());
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
// This is an hack for supporting both Spring 1.2.x and 2.0.x
super.setUrlPathHelper(urlPathHelper);
this.urlPathHelper = urlPathHelper;
}
/**
* Set the prefix to prepend to the request URL filename
* to build a view name.
*/
public void setPrefix(String prefix) {
this.prefix = (prefix != null ? prefix : "");
}
/**
* Return the prefix to prepend to the request URL filename.
*/
protected String getPrefix() {
return prefix;
}
/**
* Set the suffix to append to the request URL filename
* to build a view name.
*/
public void setSuffix(String suffix) {
this.suffix = (suffix != null ? suffix : "");
}
/**
* Return the suffix to append to the request URL filename.
*/
protected String getSuffix() {
return suffix;
}
/**
* Returns view name based on the URL filename,
* with prefix/suffix applied when appropriate.
* @see #extractViewNameFromUrlPath
* @see #setPrefix
* @see #setSuffix
*/
protected String getViewNameForUrlPath(String urlPath) {
String viewName = (String) this.viewNameCache.get(urlPath);
if (viewName == null) {
viewName = extractViewNameFromUrlPath(urlPath);
viewName = postProcessViewName(viewName);
this.viewNameCache.put(urlPath, viewName);
}
return viewName;
}
/**
* Return the name of the view to render for this request, using the
* {@link #getViewNameForUrlPath(String urlPath)} method.
* @param request current HTTP request
* @return a view name for this request (never <code>null</code>)
* @see #handleRequestInternal
* @see #setAlwaysUseFullPath
* @see #setUrlDecode
*/
protected String getViewNameForRequest(HttpServletRequest request) {
String urlPath = this.urlPathHelper.getLookupPathForRequest(request);
return this.getViewNameForUrlPath(urlPath);
}
/**
* @param uri the request URI (e.g. "/foo/index.html")
* @return the extracted URI filename (e.g. "foo/index")
*/
protected String extractViewNameFromUrlPath(String targetUrl) {
if (targetUrl.charAt(0) == '/') targetUrl = targetUrl.substring(1);
if (targetUrl.lastIndexOf('.') != -1) targetUrl = targetUrl.substring(0, targetUrl.lastIndexOf('.'));
return targetUrl;
}
/**
* Build the full view name based on the given view name
* as indicated by the URL path.
* <p>The default implementation simply applies prefix and suffix.
* This can be overridden, for example, to manipulate upper case
* / lower case, etc.
* @param viewName the original view name, as indicated by the URL path
* @return the full view name to use
* @see #getPrefix()
* @see #getSuffix()
*/
protected String postProcessViewName(String viewName) {
return getPrefix() + viewName + getSuffix();
}
}