blob: dab5089d97b4143d1a2b8cc55910e8c030ed1cda [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. The ASF licenses this file to You
* 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. For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
package org.apache.roller.weblogger.ui.rendering.util;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.WeblogEntryManager;
import org.apache.roller.weblogger.business.WebloggerFactory;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.ThemeTemplate;
import org.apache.roller.weblogger.pojos.WeblogCategory;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.apache.roller.weblogger.pojos.WeblogTemplate;
import org.apache.roller.weblogger.util.URLUtilities;
import org.apache.roller.weblogger.util.Utilities;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Represents a request for a Roller weblog page.
*
* any url from ... /roller-ui/rendering/page/*
*
* We use this class as a helper to parse an incoming url and sort out the
* information embedded in the url for later use.
*/
public class WeblogPageRequest extends WeblogRequest {
private static Log log = LogFactory.getLog(WeblogPageRequest.class);
private static final String PAGE_SERVLET = "/roller-ui/rendering/page";
// lightweight attributes
private String context = null;
private String weblogAnchor = null;
private String weblogPageName = null;
private String weblogCategoryName = null;
private String weblogDate = null;
private List tags = null;
private int pageNum = 0;
private Map customParams = new HashMap();
// heavyweight attributes
private WeblogEntry weblogEntry = null;
private ThemeTemplate weblogPage = null;
private WeblogCategory weblogCategory = null;
// Page hits
private boolean websitePageHit = false;
private boolean otherPageHit = false;
public WeblogPageRequest() {
}
/**
* Construct the WeblogPageRequest by parsing the incoming url
*/
public WeblogPageRequest(HttpServletRequest request)
throws InvalidRequestException {
// let our parent take care of their business first
// parent determines weblog handle and locale if specified
super(request);
String servlet = request.getServletPath();
// we only want the path info left over from after our parents parsing
String pathInfo = this.getPathInfo();
// parse the request object and figure out what we've got
log.debug("parsing path " + pathInfo);
// was this request bound for the right servlet?
if (!isValidDestination(servlet)) {
throw new InvalidRequestException(
"invalid destination for request, "
+ request.getRequestURL());
}
/*
* parse path info
*
* we expect one of the following forms of url ...
*
* /entry/<anchor> - permalink /date/<YYYYMMDD> - date collection view
* /category/<category> - category collection view /tags/<tag>+<tag> -
* tags /page/<pagelink> - custom page
*
* path info may be null, which indicates the weblog homepage
*/
if (pathInfo != null && pathInfo.trim().length() > 0) {
// all views use 2 path elements
String[] pathElements = pathInfo.split("/", 2);
// the first part of the path always represents the context
this.context = pathElements[0];
// now check the rest of the path and extract other details
if (pathElements.length == 2) {
if ("entry".equals(this.context)) {
this.weblogAnchor = URLUtilities.decode(pathElements[1]);
// Other page
otherPageHit = true;
} else if ("date".equals(this.context)) {
if (this.isValidDateString(pathElements[1])) {
this.weblogDate = pathElements[1];
} else {
throw new InvalidRequestException("invalid date, "
+ request.getRequestURL());
}
// Other page
otherPageHit = true;
} else if ("category".equals(this.context)) {
this.weblogCategoryName = URLUtilities
.decode(pathElements[1]);
// Other page
otherPageHit = true;
} else if ("page".equals(this.context)) {
this.weblogPageName = pathElements[1];
String tagsString = request.getParameter("tags");
if (tagsString != null) {
this.tags = Utilities.splitStringAsTags(URLUtilities
.decode(tagsString));
}
// Other page, we do not want css etc stuff so filter out
if (!pathElements[1].contains(".")) {
otherPageHit = true;
}
} else if ("tags".equals(this.context)) {
String tagsString = pathElements[1].replace('+', ' ');
this.tags = Utilities.splitStringAsTags(URLUtilities
.decode(tagsString));
int maxSize = WebloggerConfig.getIntProperty(
"tags.queries.maxIntersectionSize", 3);
if (this.tags.size() > maxSize) {
throw new InvalidRequestException(
"max number of tags allowed is " + maxSize
+ ", " + request.getRequestURL());
}
// Other page
otherPageHit = true;
} else {
throw new InvalidRequestException("context " + this.context
+ "not supported, " + request.getRequestURL());
}
} else {
// empty data is only allowed for the tags section
if (!"tags".equals(this.context)) {
throw new InvalidRequestException("invalid index page, "
+ request.getRequestURL());
}
}
} else {
// default page
websitePageHit = true;
}
/*
* parse request parameters
*
* the only params we currently allow are: date - specifies a weblog
* date string cat - specifies a weblog category anchor - specifies a
* weblog entry (old way) entry - specifies a weblog entry
*
* we only allow request params if the path info is null or on user
* defined pages (for backwards compatability). this way we prevent
* mixing of path based and query param style urls.
*/
if (pathInfo == null || this.weblogPageName != null) {
// check for entry/anchor params which indicate permalink
if (request.getParameter("entry") != null) {
String anchor = request.getParameter("entry");
if (StringUtils.isNotEmpty(anchor)) {
this.weblogAnchor = anchor;
}
} else if (request.getParameter("anchor") != null) {
String anchor = request.getParameter("anchor");
if (StringUtils.isNotEmpty(anchor)) {
this.weblogAnchor = anchor;
}
}
// only check for other params if we didn't find an anchor above or
// tags
if (this.weblogAnchor == null && this.tags == null) {
if (request.getParameter("date") != null) {
String date = request.getParameter("date");
if (this.isValidDateString(date)) {
this.weblogDate = date;
} else {
throw new InvalidRequestException("invalid date, "
+ request.getRequestURL());
}
}
if (request.getParameter("cat") != null) {
this.weblogCategoryName = URLUtilities.decode(request
.getParameter("cat"));
}
}
}
// page request param is supported in all views
if (request.getParameter("page") != null) {
String pageInt = request.getParameter("page");
try {
this.pageNum = Integer.parseInt(pageInt);
} catch (NumberFormatException e) {
// ignored, bad input
}
}
// build customParams Map, we remove built-in params because we only
// want this map to represent params defined by the template author
customParams = new HashMap(request.getParameterMap());
customParams.remove("entry");
customParams.remove("anchor");
customParams.remove("date");
customParams.remove("cat");
customParams.remove("page");
customParams.remove("tags");
if (log.isDebugEnabled()) {
log.debug("context = " + this.context);
log.debug("weblogAnchor = " + this.weblogAnchor);
log.debug("weblogDate = " + this.weblogDate);
log.debug("weblogCategory = " + this.weblogCategoryName);
log.debug("tags = " + this.tags);
log.debug("weblogPage = " + this.weblogPageName);
log.debug("pageNum = " + this.pageNum);
}
}
boolean isValidDestination(String servlet) {
return (servlet != null && PAGE_SERVLET.equals(servlet));
}
private boolean isValidDateString(String dateString) {
// string must be all numeric and 6 or 8 characters
return (dateString != null && StringUtils.isNumeric(dateString) && (dateString
.length() == 6 || dateString.length() == 8));
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public String getWeblogAnchor() {
return weblogAnchor;
}
public void setWeblogAnchor(String weblogAnchor) {
this.weblogAnchor = weblogAnchor;
}
public String getWeblogPageName() {
return weblogPageName;
}
public void setWeblogPageName(String weblogPage) {
this.weblogPageName = weblogPage;
}
public String getWeblogCategoryName() {
return weblogCategoryName;
}
public void setWeblogCategoryName(String weblogCategory) {
this.weblogCategoryName = weblogCategory;
}
public String getWeblogDate() {
return weblogDate;
}
public void setWeblogDate(String weblogDate) {
this.weblogDate = weblogDate;
}
public int getPageNum() {
return pageNum;
}
public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}
public Map getCustomParams() {
return customParams;
}
public void setCustomParams(Map customParams) {
this.customParams = customParams;
}
public List getTags() {
return tags;
}
public void setTags(List tags) {
this.tags = tags;
}
public WeblogEntry getWeblogEntry() {
if (weblogEntry == null && weblogAnchor != null) {
try {
WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
.getWeblogEntryManager();
weblogEntry = wmgr.getWeblogEntryByAnchor(getWeblog(),
weblogAnchor);
} catch (WebloggerException ex) {
log.error("Error getting weblog entry " + weblogAnchor, ex);
}
}
return weblogEntry;
}
public void setWeblogEntry(WeblogEntry weblogEntry) {
this.weblogEntry = weblogEntry;
}
public ThemeTemplate getWeblogPage() {
if (weblogPage == null && weblogPageName != null) {
try {
weblogPage = getWeblog().getTheme().getTemplateByLink(
weblogPageName);
} catch (WebloggerException ex) {
log.error("Error getting weblog page " + weblogPageName, ex);
}
}
return weblogPage;
}
public void setWeblogPage(WeblogTemplate weblogPage) {
this.weblogPage = weblogPage;
}
public WeblogCategory getWeblogCategory() {
if (weblogCategory == null && weblogCategoryName != null) {
try {
WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
.getWeblogEntryManager();
weblogCategory = wmgr.getWeblogCategoryByName(getWeblog(),
weblogCategoryName);
} catch (WebloggerException ex) {
log.error(
"Error getting weblog category " + weblogCategoryName,
ex);
}
}
return weblogCategory;
}
public void setWeblogCategory(WeblogCategory weblogCategory) {
this.weblogCategory = weblogCategory;
}
/**
* Checks if is website page hit.
*
* @return true, if is website page hit
*/
public boolean isWebsitePageHit() {
return websitePageHit;
}
/**
* Sets the website page hit.
*
* @param websitePageHit
* the new website page hit
*/
public void setWebsitePageHit(boolean websitePageHit) {
this.websitePageHit = websitePageHit;
}
/**
* Checks if is other page hit.
*
* @return true, if is other page hit
*/
public boolean isOtherPageHit() {
return otherPageHit;
}
/**
* Sets the other page hit.
*
* @param otherPageHit
* the new other page hit
*/
public void setOtherPageHit(boolean otherPageHit) {
this.otherPageHit = otherPageHit;
}
}