roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From snoopd...@apache.org
Subject svn commit: r1546816 [2/4] - in /roller/branches/rome2: ./ app/src/main/java/org/apache/roller/planet/business/ app/src/main/java/org/apache/roller/planet/business/fetcher/ app/src/main/java/org/apache/roller/weblogger/business/ app/src/main/java/org/a...
Date Sun, 01 Dec 2013 14:39:52 GMT
Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/FeedServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/FeedServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/FeedServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/FeedServlet.java Sun Dec  1 14:39:51 2013
@@ -93,57 +93,61 @@ public class FeedServlet extends HttpSer
             feedRequest = new WeblogFeedRequest(request);
 
             weblog = feedRequest.getWeblog();
-            if(weblog == null) {
-                throw new WebloggerException("unable to lookup weblog: "+
-                        feedRequest.getWeblogHandle());
+            if (weblog == null) {
+                throw new WebloggerException("unable to lookup weblog: "
+                        + feedRequest.getWeblogHandle());
             }
 
             // is this the site-wide weblog?
-            isSiteWide = WebloggerRuntimeConfig.isSiteWideWeblog(feedRequest.getWeblogHandle());
+            isSiteWide = WebloggerRuntimeConfig.isSiteWideWeblog(feedRequest
+                    .getWeblogHandle());
 
-        } catch(Exception e) {
+        } catch (Exception e) {
             // invalid feed request format or weblog doesn't exist
             log.debug("error creating weblog feed request", e);
             response.sendError(HttpServletResponse.SC_NOT_FOUND);
             return;
         }
 
-
         // determine the lastModified date for this content
         long lastModified = System.currentTimeMillis();
-        if(isSiteWide) {
+        if (isSiteWide) {
             lastModified = siteWideCache.getLastModified().getTime();
         } else if (weblog.getLastModified() != null) {
             lastModified = weblog.getLastModified().getTime();
         }
 
         // Respond with 304 Not Modified if it is not modified.
-        if (ModDateHeaderUtil.respondIfNotModified(request,response,lastModified)) {
+        if (ModDateHeaderUtil.respondIfNotModified(request, response,
+                lastModified, feedRequest.getDeviceType())) {
             return;
         }
 
         // set last-modified date
-        ModDateHeaderUtil.setLastModifiedHeader(response, lastModified);
+        ModDateHeaderUtil.setLastModifiedHeader(response, lastModified,
+                feedRequest.getDeviceType());
 
         // set content type
         String accepts = request.getHeader("Accept");
         String userAgent = request.getHeader("User-Agent");
-        if (WebloggerRuntimeConfig.getBooleanProperty("site.newsfeeds.styledFeeds") &&
-            accepts != null && accepts.indexOf("*/*") != -1 &&
-            userAgent != null && userAgent.startsWith("Mozilla")) {
-            // client is a browser and feed style is enabled so we want 
-            // browsers to load the page rather than popping up the download 
+        if (WebloggerRuntimeConfig
+                .getBooleanProperty("site.newsfeeds.styledFeeds")
+                && accepts != null
+                && accepts.contains("*/*")
+                && userAgent != null && userAgent.startsWith("Mozilla")) {
+            // client is a browser and feed style is enabled so we want
+            // browsers to load the page rather than popping up the download
             // dialog, so we provide a content-type that browsers will display
             response.setContentType("text/xml");
-        } else if("rss".equals(feedRequest.getFormat())) {
+        } else if ("rss".equals(feedRequest.getFormat())) {
             response.setContentType("application/rss+xml; charset=utf-8");
-        } else if("atom".equals(feedRequest.getFormat())) {
+        } else if ("atom".equals(feedRequest.getFormat())) {
             response.setContentType("application/atom+xml; charset=utf-8");
         }
 
         // generate cache key
         String cacheKey = null;
-        if(isSiteWide) {
+        if (isSiteWide) {
             cacheKey = siteWideCache.generateKey(feedRequest);
         } else {
             cacheKey = weblogFeedCache.generateKey(feedRequest);
@@ -151,78 +155,86 @@ public class FeedServlet extends HttpSer
 
         // cached content checking
         CachedContent cachedContent = null;
-        if(isSiteWide) {
+        if (isSiteWide) {
             cachedContent = (CachedContent) siteWideCache.get(cacheKey);
         } else {
-            cachedContent = (CachedContent) weblogFeedCache.get(cacheKey, lastModified);
+            cachedContent = (CachedContent) weblogFeedCache.get(cacheKey,
+                    lastModified);
         }
 
-        if(cachedContent != null) {
-            log.debug("HIT "+cacheKey);
+        if (cachedContent != null) {
+            log.debug("HIT " + cacheKey);
 
             response.setContentLength(cachedContent.getContent().length);
             response.getOutputStream().write(cachedContent.getContent());
             return;
 
         } else {
-            log.debug("MISS "+cacheKey);
+            log.debug("MISS " + cacheKey);
         }
 
-        // validation.  make sure that request input makes sense.
+        // validation. make sure that request input makes sense.
         boolean invalid = false;
         if (feedRequest.getLocale() != null
                 && !feedRequest.getWeblog().isEnableMultiLang()) {
             invalid = true;
         }
-        if(feedRequest.getWeblogCategoryName() != null) {
-            
-            // category specified.  category must exist.
-            if(feedRequest.getWeblogCategory() == null) {
+        if (feedRequest.getWeblogCategoryName() != null) {
+
+            // category specified. category must exist.
+            if (feedRequest.getWeblogCategory() == null) {
                 invalid = true;
             }
-            
-        } else if(feedRequest.getTags() != null && feedRequest.getTags().size() > 0) {
-            
+
+        } else if (feedRequest.getTags() != null
+                && feedRequest.getTags().size() > 0) {
+
             try {
-                // tags specified.  make sure they exist.
-                WeblogEntryManager wmgr = WebloggerFactory.getWeblogger().getWeblogEntryManager();
-                invalid = !wmgr.getTagComboExists(feedRequest.getTags(), (isSiteWide) ? null : weblog);
+                // tags specified. make sure they exist.
+                WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
+                        .getWeblogEntryManager();
+                invalid = !wmgr.getTagComboExists(feedRequest.getTags(),
+                        (isSiteWide) ? null : weblog);
             } catch (WebloggerException ex) {
                 invalid = true;
             }
         }
-        
-        if(invalid) {
+
+        if (invalid) {
             if (!response.isCommitted()) {
                 response.reset();
             }
             response.sendError(HttpServletResponse.SC_NOT_FOUND);
             return;
         }
-        
-        
+
         // do we need to force a specific locale for the request?
-        if(feedRequest.getLocale() == null && !weblog.isShowAllLangs()) {
+        if (feedRequest.getLocale() == null && !weblog.isShowAllLangs()) {
             feedRequest.setLocale(weblog.getLocale());
         }
-        
+
         // looks like we need to render content
         HashMap model = new HashMap();
         String pageId = null;
         try {
             // determine what template to render with
-            boolean siteWide = WebloggerRuntimeConfig.isSiteWideWeblog(weblog.getHandle());
-           if (siteWide && "entries".equals(feedRequest.getType()) && feedRequest.getTerm() != null) {
+            boolean siteWide = WebloggerRuntimeConfig.isSiteWideWeblog(weblog
+                    .getHandle());
+            if (siteWide && "entries".equals(feedRequest.getType())
+                    && feedRequest.getTerm() != null) {
                 pageId = "site-search-atom.vm";
 
-           } else if ("entries".equals(feedRequest.getType()) && feedRequest.getTerm() != null) {
+            } else if ("entries".equals(feedRequest.getType())
+                    && feedRequest.getTerm() != null) {
                 pageId = "feeds/weblog-search-atom.vm";
 
             } else if (siteWide) {
-                pageId = "site-"+feedRequest.getType()+"-"+feedRequest.getFormat()+".vm";
+                pageId = "site-" + feedRequest.getType() + "-"
+                        + feedRequest.getFormat() + ".vm";
 
             } else {
-                pageId = "weblog-"+feedRequest.getType()+"-"+feedRequest.getFormat()+".vm";
+                pageId = "weblog-" + feedRequest.getType() + "-"
+                        + feedRequest.getFormat() + ".vm";
             }
 
             // populate the rendering model
@@ -230,45 +242,50 @@ public class FeedServlet extends HttpSer
             initData.put("parsedRequest", feedRequest);
 
             // define url strategy
-            initData.put("urlStrategy", WebloggerFactory.getWeblogger().getUrlStrategy());
+            initData.put("urlStrategy", WebloggerFactory.getWeblogger()
+                    .getUrlStrategy());
 
             // Load models for feeds
-            String feedModels = WebloggerConfig.getProperty("rendering.feedModels");
+            String feedModels = WebloggerConfig
+                    .getProperty("rendering.feedModels");
             ModelLoader.loadModels(feedModels, model, initData, true);
 
             // Load special models for site-wide blog
 
             if (siteWide) {
-                String siteModels = WebloggerConfig.getProperty("rendering.siteModels");
+                String siteModels = WebloggerConfig
+                        .getProperty("rendering.siteModels");
                 ModelLoader.loadModels(siteModels, model, initData, true);
             }
 
             // Load weblog custom models
             ModelLoader.loadCustomModels(weblog, model, initData);
-            
+
             // Load search models if search feed
-            if ("entries".equals(feedRequest.getType()) && feedRequest.getTerm() != null) {               
-                ModelLoader.loadModels(SearchResultsFeedModel.class.getName(), model, initData, true);
-            }                        
+            if ("entries".equals(feedRequest.getType())
+                    && feedRequest.getTerm() != null) {
+                ModelLoader.loadModels(SearchResultsFeedModel.class.getName(),
+                        model, initData, true);
+            }
 
         } catch (WebloggerException ex) {
             log.error("ERROR loading model for page", ex);
 
-            if(!response.isCommitted()) {
+            if (!response.isCommitted()) {
                 response.reset();
             }
             response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             return;
         }
 
-
         // lookup Renderer we are going to use
         Renderer renderer = null;
         try {
             log.debug("Looking up renderer");
             Template template = new StaticTemplate(pageId, "velocity");
-            renderer = RendererManager.getRenderer(template, MobileDeviceRepository.DeviceType.standard);
-        } catch(Exception e) {
+            renderer = RendererManager.getRenderer(template,
+                    MobileDeviceRepository.DeviceType.standard);
+        } catch (Exception e) {
             // nobody wants to render my content :(
 
             // TODO: this log message has been disabled because it fills up
@@ -278,7 +295,7 @@ public class FeedServlet extends HttpSer
             // at some point we should have better validation on the input so
             // that we can quickly dispatch invalid feed requests and only
             // get this far if we expect the template to be found
-            //log.error("Couldn't find renderer for page "+pageId, e);
+            // log.error("Couldn't find renderer for page "+pageId, e);
 
             if (!response.isCommitted()) {
                 response.reset();
@@ -287,7 +304,7 @@ public class FeedServlet extends HttpSer
             return;
         }
 
-        // render content.  use default size of about 24K for a standard page
+        // render content. use default size of about 24K for a standard page
         CachedContent rendererOutput = new CachedContent(24567);
         try {
             log.debug("Doing rendering");
@@ -298,7 +315,7 @@ public class FeedServlet extends HttpSer
             rendererOutput.close();
         } catch (Exception e) {
             // bummer, error during rendering
-            log.error("Error during rendering for page "+pageId, e);
+            log.error("Error during rendering for page " + pageId, e);
 
             if (!response.isCommitted()) {
                 response.reset();
@@ -307,7 +324,6 @@ public class FeedServlet extends HttpSer
             return;
         }
 
-
         // post rendering process
 
         // flush rendered content to response
@@ -315,9 +331,9 @@ public class FeedServlet extends HttpSer
         response.setContentLength(rendererOutput.getContent().length);
         response.getOutputStream().write(rendererOutput.getContent());
 
-        // cache rendered content.  only cache if user is not logged in?
-        log.debug("PUT "+cacheKey);
-        if(isSiteWide) {
+        // cache rendered content. only cache if user is not logged in?
+        log.debug("PUT " + cacheKey);
+        if (isSiteWide) {
             siteWideCache.put(cacheKey, rendererOutput);
         } else {
             weblogFeedCache.put(cacheKey, rendererOutput);

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java Sun Dec  1 14:39:51 2013
@@ -67,616 +67,617 @@ import java.util.regex.Pattern;
  */
 public class PageServlet extends HttpServlet {
 
-	private static Log log = LogFactory.getLog(PageServlet.class);
-	// for referrer processing
-	private boolean processReferrers = true;
-	private static Pattern robotPattern = null;
-	// for caching
-	private boolean excludeOwnerPages = false;
-	private WeblogPageCache weblogPageCache = null;
-	private SiteWideCache siteWideCache = null;
-
-	// Development theme reloading
-	Boolean themeReload = false;
-
-	/**
-	 * Init method for this servlet
-	 */
-	public void init(ServletConfig servletConfig) throws ServletException {
-
-		super.init(servletConfig);
-
-		log.info("Initializing PageServlet");
-
-		this.excludeOwnerPages = WebloggerConfig
-				.getBooleanProperty("cache.excludeOwnerEditPages");
-
-		// get a reference to the weblog page cache
-		this.weblogPageCache = WeblogPageCache.getInstance();
-
-		// get a reference to the site wide cache
-		this.siteWideCache = SiteWideCache.getInstance();
-
-		// see if built-in referrer processing is enabled
-		this.processReferrers = WebloggerConfig
-				.getBooleanProperty("referrers.processing.enabled");
-
-		log.info("Referrer processing enabled = " + this.processReferrers);
-
-		// check for possible robot pattern
-		String robotPatternStr = WebloggerConfig
-				.getProperty("referrer.robotCheck.userAgentPattern");
-		if (robotPatternStr != null && robotPatternStr.length() > 0) {
-			// Parse the pattern, and store the compiled form.
-			try {
-				robotPattern = Pattern.compile(robotPatternStr);
-			} catch (Exception e) {
-				// Most likely a PatternSyntaxException; log and continue as if
-				// it is not set.
-				log.error(
-						"Error parsing referrer.robotCheck.userAgentPattern value '"
-								+ robotPatternStr
-								+ "'.  Robots will not be filtered. ", e);
-			}
-		}
-
-		// Development theme reloading
-		themeReload = WebloggerConfig.getBooleanProperty("themes.reload.mode");
-	}
-
-	/**
-	 * Handle GET requests for weblog pages.
-	 */
-	public void doGet(HttpServletRequest request, HttpServletResponse response)
-			throws ServletException, IOException {
-
-		log.debug("Entering");
-
-		// do referrer processing, if it's enabled
-		// NOTE: this *must* be done first because it triggers a hibernate flush
-		// which will close the active session and cause lazy init exceptions
-		// otherwise
-		if (this.processReferrers) {
-			boolean spam = this.processReferrer(request);
-			if (spam) {
-				log.debug("spammer, giving 'em a 403");
-				if (!response.isCommitted()) {
-					response.reset();
-				}
-				response.sendError(HttpServletResponse.SC_FORBIDDEN);
-				return;
-			}
-		}
-
-		Weblog weblog = null;
-		boolean isSiteWide = false;
-
-		WeblogPageRequest pageRequest = null;
-		try {
-			pageRequest = new WeblogPageRequest(request);
-
-			weblog = pageRequest.getWeblog();
-			if (weblog == null) {
-				throw new WebloggerException("unable to lookup weblog: "
-						+ pageRequest.getWeblogHandle());
-			}
-
-			// is this the site-wide weblog?
-			isSiteWide = WebloggerRuntimeConfig.isSiteWideWeblog(pageRequest
-					.getWeblogHandle());
-		} catch (Exception e) {
-			// some kind of error parsing the request or looking up weblog
-			log.debug("error creating page request", e);
-			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
-
-		// determine the lastModified date for this content
-		long lastModified = System.currentTimeMillis();
-		if (isSiteWide) {
-			lastModified = siteWideCache.getLastModified().getTime();
-		} else if (weblog.getLastModified() != null) {
-			lastModified = weblog.getLastModified().getTime();
-		}
-
-		// 304 Not Modified handling.
-		// We skip this for logged in users to avoid the scenerio where a user
-		// views their weblog, logs in, then gets a 304 without the 'edit' links
-		if (!pageRequest.isLoggedIn()) {
-			if (ModDateHeaderUtil.respondIfNotModified(request, response,
-					lastModified)) {
-				return;
-			} else {
-				// set last-modified date
-				ModDateHeaderUtil.setLastModifiedHeader(response, lastModified);
-			}
-		}
-
-		// generate cache key
-		String cacheKey = null;
-		if (isSiteWide) {
-			cacheKey = siteWideCache.generateKey(pageRequest);
-		} else {
-			cacheKey = weblogPageCache.generateKey(pageRequest);
-		}
-
-		// Development only. Reload if theme has been modified
-		if (themeReload
-				&& !weblog.getEditorTheme()
-						.equals(WeblogTemplate.ACTION_CUSTOM)
-				&& (pageRequest.getPathInfo() == null || pageRequest
-						.getPathInfo() != null)) {
-			try {
-				ThemeManager manager = WebloggerFactory.getWeblogger()
-						.getThemeManager();
-				boolean reloaded = manager.reLoadThemeFromDisk(weblog
-						.getEditorTheme());
-				if (reloaded) {
-					if (isSiteWide) {
-						siteWideCache.clear();
-					} else {
-						weblogPageCache.clear();
-					}
-					I18nMessages.reloadBundle(weblog.getLocaleInstance());
-				}
-
-			} catch (Exception ex) {
-				log.error("ERROR - reloading theme " + ex);
-			}
-		}
-
-		// cached content checking
-		if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn())
-				&& request.getAttribute("skipCache") == null) {
-
-			CachedContent cachedContent = null;
-			if (isSiteWide) {
-				cachedContent = (CachedContent) siteWideCache.get(cacheKey);
-			} else {
-				cachedContent = (CachedContent) weblogPageCache.get(cacheKey,
-						lastModified);
-			}
-
-			if (cachedContent != null) {
-				log.debug("HIT " + cacheKey);
-
-				// allow for hit counting
-				if (!isSiteWide) {
-					this.processHit(weblog, request.getRequestURL().toString(),
-							request.getHeader("referer"));
-				}
-
-				response.setContentLength(cachedContent.getContent().length);
-				response.setContentType(cachedContent.getContentType());
-				response.getOutputStream().write(cachedContent.getContent());
-				return;
-			} else {
-				log.debug("MISS " + cacheKey);
-			}
-		}
-
-		log.debug("Looking for template to use for rendering");
-
-		// figure out what template to use
-		ThemeTemplate page = null;
-
-		// If this is a popup request, then deal with it specially
-		// TODO: do we really need to keep supporting this?
-		if (request.getParameter("popup") != null) {
-			try {
-				// Does user have a popupcomments page?
-				page = weblog.getTheme().getTemplateByName("_popupcomments");
-			} catch (Exception e) {
-				// ignored ... considered page not found
-			}
-
-			// User doesn't have one so return the default
-			if (page == null) {
-				page = new StaticThemeTemplate(
-						"templates/weblog/popupcomments.vm", "velocity");
-			}
-
-			// If request specified the page, then go with that
-		} else if ("page".equals(pageRequest.getContext())) {
-			page = pageRequest.getWeblogPage();
-
-			// if we don't have this page then 404, we don't let
-			// this one fall through to the default template
-			if (page == null) {
-				if (!response.isCommitted()) {
-					response.reset();
-				}
-				response.sendError(HttpServletResponse.SC_NOT_FOUND);
-				return;
-			}
-
-			// If request specified tags section index, then look for custom
-			// template
-		} else if ("tags".equals(pageRequest.getContext())
-				&& pageRequest.getTags() != null) {
-			try {
-				page = weblog.getTheme().getTemplateByAction(
-						ThemeTemplate.ACTION_TAGSINDEX);
-			} catch (Exception e) {
-				log.error("Error getting weblog page for action 'tagsIndex'", e);
-			}
-
-			// if we don't have a custom tags page then 404, we don't let
-			// this one fall through to the default template
-			if (page == null) {
-				if (!response.isCommitted()) {
-					response.reset();
-				}
-				response.sendError(HttpServletResponse.SC_NOT_FOUND);
-				return;
-			}
-
-			// If this is a permalink then look for a permalink template
-		} else if (pageRequest.getWeblogAnchor() != null) {
-			try {
-				page = weblog.getTheme().getTemplateByAction(
-						ThemeTemplate.ACTION_PERMALINK);
-			} catch (Exception e) {
-				log.error("Error getting weblog page for action 'permalink'", e);
-			}
-		}
-
-		// if we haven't found a page yet then try our default page
-		if (page == null) {
-			try {
-				page = weblog.getTheme().getDefaultTemplate();
-			} catch (Exception e) {
-				log.error(
-						"Error getting default page for weblog = "
-								+ weblog.getHandle(), e);
-			}
-		}
-
-		// Still no page? Then that is a 404
-		if (page == null) {
-			if (!response.isCommitted()) {
-				response.reset();
-			}
-			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
-
-		log.debug("page found, dealing with it");
-
-		// validation. make sure that request input makes sense.
-		boolean invalid = false;
-		if (pageRequest.getWeblogPageName() != null && page.isHidden()) {
-			invalid = true;
-		}
-		if (pageRequest.getLocale() != null) {
-
-			// locale view only allowed if weblog has enabled it
-			if (!pageRequest.getWeblog().isEnableMultiLang()) {
-				invalid = true;
-			}
-		}
-		if (pageRequest.getWeblogAnchor() != null) {
-
-			// permalink specified.
-			// entry must exist, be published before current time, and locale
-			// must match
-			WeblogEntry entry = pageRequest.getWeblogEntry();
-			if (entry == null) {
-				invalid = true;
-			} else if (pageRequest.getLocale() != null
-					&& !entry.getLocale().startsWith(pageRequest.getLocale())) {
-				invalid = true;
-			} else if (!entry.isPublished()) {
-				invalid = true;
-			} else if (new Date().before(entry.getPubTime())) {
-				invalid = true;
-			}
-		} else if (pageRequest.getWeblogCategoryName() != null) {
-
-			// category specified. category must exist.
-			if (pageRequest.getWeblogCategory() == null) {
-				invalid = true;
-			}
-		} else if (pageRequest.getTags() != null
-				&& pageRequest.getTags().size() > 0) {
-
-			try {
-				// tags specified. make sure they exist.
-				WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
-						.getWeblogEntryManager();
-				invalid = !wmgr.getTagComboExists(pageRequest.getTags(),
-						(isSiteWide) ? null : weblog);
-			} catch (WebloggerException ex) {
-				invalid = true;
-			}
-		}
-
-		if (invalid) {
-			log.debug("page failed validation, bailing out");
-			if (!response.isCommitted()) {
-				response.reset();
-			}
-			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
-
-		// do we need to force a specific locale for the request?
-		if (pageRequest.getLocale() == null && !weblog.isShowAllLangs()) {
-			pageRequest.setLocale(weblog.getLocale());
-		}
-
-		// allow for hit counting
-		if (!isSiteWide) {
-			this.processHit(weblog, request.getRequestURL().toString(),
-					request.getHeader("referer"));
-		}
-
-		// looks like we need to render content
-		// set the content deviceType
-		String contentType = "text/html; charset=utf-8";
-		if (StringUtils.isNotEmpty(page.getOutputContentType())) {
-			contentType = page.getOutputContentType() + "; charset=utf-8";
-		} else {
-			String mimeType = RollerContext.getServletContext().getMimeType(
-					page.getLink());
-			if (mimeType != null) {
-				// we found a match ... set the content deviceType
-				contentType = mimeType + "; charset=utf-8";
-			} else {
-				contentType = "text/html; charset=utf-8";
-			}
-		}
-
-		HashMap model = new HashMap();
-		try {
-			PageContext pageContext = JspFactory.getDefaultFactory()
-					.getPageContext(this, request, response, "", false, 8192,
-							true);
-
-			// special hack for menu tag
-			request.setAttribute("pageRequest", pageRequest);
-
-			// populate the rendering model
-			Map initData = new HashMap();
-			initData.put("requestParameters", request.getParameterMap());
-			initData.put("parsedRequest", pageRequest);
-			initData.put("pageContext", pageContext);
-
-			// define url strategy
-			initData.put("urlStrategy", WebloggerFactory.getWeblogger()
-					.getUrlStrategy());
-
-			// if this was a comment posting, check for comment form
-			WeblogEntryCommentForm commentForm = (WeblogEntryCommentForm) request
-					.getAttribute("commentForm");
-			if (commentForm != null) {
-				initData.put("commentForm", commentForm);
-			}
-
-			// Load models for pages
-			String pageModels = WebloggerConfig
-					.getProperty("rendering.pageModels");
-			ModelLoader.loadModels(pageModels, model, initData, true);
-			// Load special models for site-wide blog
-			if (WebloggerRuntimeConfig.isSiteWideWeblog(weblog.getHandle())) {
-				String siteModels = WebloggerConfig
-						.getProperty("rendering.siteModels");
-				ModelLoader.loadModels(siteModels, model, initData, true);
-			}
-
-			// Load weblog custom models
-			ModelLoader.loadCustomModels(weblog, model, initData);
-
-		} catch (WebloggerException ex) {
-			log.error("Error loading model objects for page", ex);
-
-			if (!response.isCommitted()) {
-				response.reset();
-			}
-			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-			return;
-		}
-
-		// lookup Renderer we are going to use
-		Renderer renderer = null;
-		try {
-			log.debug("Looking up renderer");
-			renderer = RendererManager.getRenderer(page,
-					pageRequest.getDeviceType());
-		} catch (Exception e) {
-			// nobody wants to render my content :(
-			log.error("Couldn't find renderer for page " + page.getId(), e);
-
-			if (!response.isCommitted()) {
-				response.reset();
-			}
-			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
-
-		// render content. use size of about 24K for a standard page
-		CachedContent rendererOutput = new CachedContent(24567, contentType);
-		try {
-			log.debug("Doing rendering");
-			renderer.render(model, rendererOutput.getCachedWriter());
-
-			// flush rendered output and close
-			rendererOutput.flush();
-			rendererOutput.close();
-		} catch (Exception e) {
-			// bummer, error during rendering
-			log.error("Error during rendering for page " + page.getId(), e);
-
-			if (!response.isCommitted()) {
-				response.reset();
-			}
-			response.sendError(HttpServletResponse.SC_NOT_FOUND);
-			return;
-		}
-
-		// post rendering process
-		// flush rendered content to response
-		log.debug("Flushing response output");
-		response.setContentType(contentType);
-		response.setContentLength(rendererOutput.getContent().length);
-		response.getOutputStream().write(rendererOutput.getContent());
-
-		// cache rendered content. only cache if user is not logged in?
-		if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn())
-				&& request.getAttribute("skipCache") == null) {
-			log.debug("PUT " + cacheKey);
-
-			// put it in the right cache
-			if (isSiteWide) {
-				siteWideCache.put(cacheKey, rendererOutput);
-			} else {
-				weblogPageCache.put(cacheKey, rendererOutput);
-			}
-		} else {
-			log.debug("SKIPPED " + cacheKey);
-		}
-
-		log.debug("Exiting");
-	}
-
-	/**
-	 * Handle POST requests.
-	 * 
-	 * We have this here because the comment servlet actually forwards some of
-	 * its requests on to us to render some pages with cusom messaging. We may
-	 * want to revisit this approach in the future and see if we can do this in
-	 * a different way, but for now this is the easy way.
-	 */
-	public void doPost(HttpServletRequest request, HttpServletResponse response)
-			throws ServletException, IOException {
-
-		// make sure caching is disabled
-		request.setAttribute("skipCache", "true");
-
-		// handle just like a GET request
-		this.doGet(request, response);
-	}
-
-	/**
-	 * Notify the hit tracker that it has an incoming page hit.
-	 */
-	private void processHit(Weblog weblog, String url, String referrer) {
-
-		HitCountQueue counter = HitCountQueue.getInstance();
-		counter.processHit(weblog, url, referrer);
-	}
-
-	/**
-	 * Process the incoming request to extract referrer info and pass it on to
-	 * the referrer processing queue for tracking.
-	 * 
-	 * @return true if referrer was spam, false otherwise
-	 */
-	private boolean processReferrer(HttpServletRequest request) {
-
-		log.debug("processing referrer for " + request.getRequestURI());
-
-		// bleh! because ref processing does a flush it will close
-		// our hibernate session and cause lazy init exceptions on
-		// objects we have fetched, so we need to use a separate
-		// page request object for this
-		WeblogPageRequest pageRequest;
-		try {
-			pageRequest = new WeblogPageRequest(request);
-		} catch (InvalidRequestException ex) {
-			return false;
-		}
-
-		// if this came from site-wide frontpage then skip it
-		if (WebloggerRuntimeConfig.isSiteWideWeblog(pageRequest
-				.getWeblogHandle())) {
-			return false;
-		}
-
-		// if this came from a robot then don't process it
-		if (robotPattern != null) {
-			String userAgent = request.getHeader("User-Agent");
-			if (userAgent != null && userAgent.length() > 0
-					&& robotPattern.matcher(userAgent).matches()) {
-				log.debug("skipping referrer from robot");
-				return false;
-			}
-		}
-
-		String referrerUrl = request.getHeader("Referer");
-		StringBuffer reqsb = request.getRequestURL();
-		if (request.getQueryString() != null) {
-			reqsb.append("?");
-			reqsb.append(request.getQueryString());
-		}
-		String requestUrl = reqsb.toString();
-
-		log.debug("referrer = " + referrerUrl);
-
-		// if this came from persons own blog then don't process it
-		String selfSiteFragment = "/" + pageRequest.getWeblogHandle();
-		if (referrerUrl != null && referrerUrl.indexOf(selfSiteFragment) != -1) {
-			log.debug("skipping referrer from own blog");
-			return false;
-		}
-
-		// validate the referrer
-		if (pageRequest != null && pageRequest.getWeblogHandle() != null) {
-
-			// Base page URLs, with and without www.
-			String basePageUrlWWW = WebloggerRuntimeConfig
-					.getAbsoluteContextURL()
-					+ "/"
-					+ pageRequest.getWeblogHandle();
-			String basePageUrl = basePageUrlWWW;
-			if (basePageUrlWWW.startsWith("http://www.")) {
-				// chop off the http://www.
-				basePageUrl = "http://" + basePageUrlWWW.substring(11);
-			}
-
-			// ignore referrers coming from users own blog
-			if (referrerUrl == null
-					|| (!referrerUrl.startsWith(basePageUrl) && !referrerUrl
-							.startsWith(basePageUrlWWW))) {
-
-				// validate the referrer
-				if (referrerUrl != null) {
-					// treat editor referral as direct
-					int lastSlash = requestUrl.indexOf('/', 8);
-					if (lastSlash == -1) {
-						lastSlash = requestUrl.length();
-					}
-					String requestSite = requestUrl.substring(0, lastSlash);
-
-					if (referrerUrl.matches(requestSite + ".*\\.rol.*")) {
-						referrerUrl = null;
-					} else if (BlacklistChecker.checkReferrer(
-							pageRequest.getWeblog(), referrerUrl)) {
-						return true;
-					}
-				}
-			} else {
-				log.debug("Ignoring referer = " + referrerUrl);
-				return false;
-			}
-		}
-
-		// referrer is valid, lets record it
-		try {
-			IncomingReferrer referrer = new IncomingReferrer();
-			referrer.setReferrerUrl(referrerUrl);
-			referrer.setRequestUrl(requestUrl);
-			referrer.setWeblogHandle(pageRequest.getWeblogHandle());
-			referrer.setWeblogAnchor(pageRequest.getWeblogAnchor());
-			referrer.setWeblogDateString(pageRequest.getWeblogDate());
-
-			ReferrerQueueManager refQueue = WebloggerFactory.getWeblogger()
-					.getReferrerQueueManager();
-			refQueue.processReferrer(referrer);
-		} catch (Exception e) {
-			log.error("Error processing referrer", e);
-		}
+    private static Log log = LogFactory.getLog(PageServlet.class);
+    // for referrer processing
+    private boolean processReferrers = true;
+    private static Pattern robotPattern = null;
+    // for caching
+    private boolean excludeOwnerPages = false;
+    private WeblogPageCache weblogPageCache = null;
+    private SiteWideCache siteWideCache = null;
+
+    // Development theme reloading
+    Boolean themeReload = false;
+
+    /**
+     * Init method for this servlet
+     */
+    public void init(ServletConfig servletConfig) throws ServletException {
+
+        super.init(servletConfig);
+
+        log.info("Initializing PageServlet");
+
+        this.excludeOwnerPages = WebloggerConfig
+                .getBooleanProperty("cache.excludeOwnerEditPages");
+
+        // get a reference to the weblog page cache
+        this.weblogPageCache = WeblogPageCache.getInstance();
+
+        // get a reference to the site wide cache
+        this.siteWideCache = SiteWideCache.getInstance();
+
+        // see if built-in referrer processing is enabled
+        this.processReferrers = WebloggerConfig
+                .getBooleanProperty("referrers.processing.enabled");
+
+        log.info("Referrer processing enabled = " + this.processReferrers);
+
+        // check for possible robot pattern
+        String robotPatternStr = WebloggerConfig
+                .getProperty("referrer.robotCheck.userAgentPattern");
+        if (robotPatternStr != null && robotPatternStr.length() > 0) {
+            // Parse the pattern, and store the compiled form.
+            try {
+                robotPattern = Pattern.compile(robotPatternStr);
+            } catch (Exception e) {
+                // Most likely a PatternSyntaxException; log and continue as if
+                // it is not set.
+                log.error(
+                        "Error parsing referrer.robotCheck.userAgentPattern value '"
+                                + robotPatternStr
+                                + "'.  Robots will not be filtered. ", e);
+            }
+        }
+
+        // Development theme reloading
+        themeReload = WebloggerConfig.getBooleanProperty("themes.reload.mode");
+    }
+
+    /**
+     * Handle GET requests for weblog pages.
+     */
+    public void doGet(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+
+        log.debug("Entering");
+
+        // do referrer processing, if it's enabled
+        // NOTE: this *must* be done first because it triggers a hibernate flush
+        // which will close the active session and cause lazy init exceptions
+        // otherwise
+        if (this.processReferrers) {
+            boolean spam = this.processReferrer(request);
+            if (spam) {
+                log.debug("spammer, giving 'em a 403");
+                if (!response.isCommitted()) {
+                    response.reset();
+                }
+                response.sendError(HttpServletResponse.SC_FORBIDDEN);
+                return;
+            }
+        }
+
+        Weblog weblog = null;
+        boolean isSiteWide = false;
+
+        WeblogPageRequest pageRequest = null;
+        try {
+            pageRequest = new WeblogPageRequest(request);
+
+            weblog = pageRequest.getWeblog();
+            if (weblog == null) {
+                throw new WebloggerException("unable to lookup weblog: "
+                        + pageRequest.getWeblogHandle());
+            }
+
+            // is this the site-wide weblog?
+            isSiteWide = WebloggerRuntimeConfig.isSiteWideWeblog(pageRequest
+                    .getWeblogHandle());
+        } catch (Exception e) {
+            // some kind of error parsing the request or looking up weblog
+            log.debug("error creating page request", e);
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        // determine the lastModified date for this content
+        long lastModified = System.currentTimeMillis();
+        if (isSiteWide) {
+            lastModified = siteWideCache.getLastModified().getTime();
+        } else if (weblog.getLastModified() != null) {
+            lastModified = weblog.getLastModified().getTime();
+        }
+
+        // 304 Not Modified handling.
+        // We skip this for logged in users to avoid the scenerio where a user
+        // views their weblog, logs in, then gets a 304 without the 'edit' links
+        if (!pageRequest.isLoggedIn()) {
+            if (ModDateHeaderUtil.respondIfNotModified(request, response,
+                    lastModified, pageRequest.getDeviceType())) {
+                return;
+            } else {
+                // set last-modified date
+                ModDateHeaderUtil.setLastModifiedHeader(response, lastModified,
+                        pageRequest.getDeviceType());
+            }
+        }
+
+        // generate cache key
+        String cacheKey = null;
+        if (isSiteWide) {
+            cacheKey = siteWideCache.generateKey(pageRequest);
+        } else {
+            cacheKey = weblogPageCache.generateKey(pageRequest);
+        }
+
+        // Development only. Reload if theme has been modified
+        if (themeReload
+                && !weblog.getEditorTheme()
+                        .equals(WeblogTemplate.ACTION_CUSTOM)
+                && (pageRequest.getPathInfo() == null || pageRequest
+                        .getPathInfo() != null)) {
+            try {
+                ThemeManager manager = WebloggerFactory.getWeblogger()
+                        .getThemeManager();
+                boolean reloaded = manager.reLoadThemeFromDisk(weblog
+                        .getEditorTheme());
+                if (reloaded) {
+                    if (isSiteWide) {
+                        siteWideCache.clear();
+                    } else {
+                        weblogPageCache.clear();
+                    }
+                    I18nMessages.reloadBundle(weblog.getLocaleInstance());
+                }
+
+            } catch (Exception ex) {
+                log.error("ERROR - reloading theme " + ex);
+            }
+        }
+
+        // cached content checking
+        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn())
+                && request.getAttribute("skipCache") == null) {
+
+            CachedContent cachedContent = null;
+            if (isSiteWide) {
+                cachedContent = (CachedContent) siteWideCache.get(cacheKey);
+            } else {
+                cachedContent = (CachedContent) weblogPageCache.get(cacheKey,
+                        lastModified);
+            }
+
+            if (cachedContent != null) {
+                log.debug("HIT " + cacheKey);
+
+                // allow for hit counting
+                if (!isSiteWide) {
+                    this.processHit(weblog, request.getRequestURL().toString(),
+                            request.getHeader("referer"));
+                }
+
+                response.setContentLength(cachedContent.getContent().length);
+                response.setContentType(cachedContent.getContentType());
+                response.getOutputStream().write(cachedContent.getContent());
+                return;
+            } else {
+                log.debug("MISS " + cacheKey);
+            }
+        }
+
+        log.debug("Looking for template to use for rendering");
+
+        // figure out what template to use
+        ThemeTemplate page = null;
+
+        // If this is a popup request, then deal with it specially
+        // TODO: do we really need to keep supporting this?
+        if (request.getParameter("popup") != null) {
+            try {
+                // Does user have a popupcomments page?
+                page = weblog.getTheme().getTemplateByName("_popupcomments");
+            } catch (Exception e) {
+                // ignored ... considered page not found
+            }
+
+            // User doesn't have one so return the default
+            if (page == null) {
+                page = new StaticThemeTemplate(
+                        "templates/weblog/popupcomments.vm", "velocity");
+            }
+
+            // If request specified the page, then go with that
+        } else if ("page".equals(pageRequest.getContext())) {
+            page = pageRequest.getWeblogPage();
+
+            // if we don't have this page then 404, we don't let
+            // this one fall through to the default template
+            if (page == null) {
+                if (!response.isCommitted()) {
+                    response.reset();
+                }
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                return;
+            }
+
+            // If request specified tags section index, then look for custom
+            // template
+        } else if ("tags".equals(pageRequest.getContext())
+                && pageRequest.getTags() != null) {
+            try {
+                page = weblog.getTheme().getTemplateByAction(
+                        ThemeTemplate.ACTION_TAGSINDEX);
+            } catch (Exception e) {
+                log.error("Error getting weblog page for action 'tagsIndex'", e);
+            }
+
+            // if we don't have a custom tags page then 404, we don't let
+            // this one fall through to the default template
+            if (page == null) {
+                if (!response.isCommitted()) {
+                    response.reset();
+                }
+                response.sendError(HttpServletResponse.SC_NOT_FOUND);
+                return;
+            }
+
+            // If this is a permalink then look for a permalink template
+        } else if (pageRequest.getWeblogAnchor() != null) {
+            try {
+                page = weblog.getTheme().getTemplateByAction(
+                        ThemeTemplate.ACTION_PERMALINK);
+            } catch (Exception e) {
+                log.error("Error getting weblog page for action 'permalink'", e);
+            }
+        }
+
+        // if we haven't found a page yet then try our default page
+        if (page == null) {
+            try {
+                page = weblog.getTheme().getDefaultTemplate();
+            } catch (Exception e) {
+                log.error(
+                        "Error getting default page for weblog = "
+                                + weblog.getHandle(), e);
+            }
+        }
+
+        // Still no page? Then that is a 404
+        if (page == null) {
+            if (!response.isCommitted()) {
+                response.reset();
+            }
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        log.debug("page found, dealing with it");
+
+        // validation. make sure that request input makes sense.
+        boolean invalid = false;
+        if (pageRequest.getWeblogPageName() != null && page.isHidden()) {
+            invalid = true;
+        }
+        if (pageRequest.getLocale() != null) {
+
+            // locale view only allowed if weblog has enabled it
+            if (!pageRequest.getWeblog().isEnableMultiLang()) {
+                invalid = true;
+            }
+        }
+        if (pageRequest.getWeblogAnchor() != null) {
+
+            // permalink specified.
+            // entry must exist, be published before current time, and locale
+            // must match
+            WeblogEntry entry = pageRequest.getWeblogEntry();
+            if (entry == null) {
+                invalid = true;
+            } else if (pageRequest.getLocale() != null
+                    && !entry.getLocale().startsWith(pageRequest.getLocale())) {
+                invalid = true;
+            } else if (!entry.isPublished()) {
+                invalid = true;
+            } else if (new Date().before(entry.getPubTime())) {
+                invalid = true;
+            }
+        } else if (pageRequest.getWeblogCategoryName() != null) {
+
+            // category specified. category must exist.
+            if (pageRequest.getWeblogCategory() == null) {
+                invalid = true;
+            }
+        } else if (pageRequest.getTags() != null
+                && pageRequest.getTags().size() > 0) {
+
+            try {
+                // tags specified. make sure they exist.
+                WeblogEntryManager wmgr = WebloggerFactory.getWeblogger()
+                        .getWeblogEntryManager();
+                invalid = !wmgr.getTagComboExists(pageRequest.getTags(),
+                        (isSiteWide) ? null : weblog);
+            } catch (WebloggerException ex) {
+                invalid = true;
+            }
+        }
+
+        if (invalid) {
+            log.debug("page failed validation, bailing out");
+            if (!response.isCommitted()) {
+                response.reset();
+            }
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        // do we need to force a specific locale for the request?
+        if (pageRequest.getLocale() == null && !weblog.isShowAllLangs()) {
+            pageRequest.setLocale(weblog.getLocale());
+        }
+
+        // allow for hit counting
+        if (!isSiteWide) {
+            this.processHit(weblog, request.getRequestURL().toString(),
+                    request.getHeader("referer"));
+        }
+
+        // looks like we need to render content
+        // set the content deviceType
+        String contentType = "text/html; charset=utf-8";
+        if (StringUtils.isNotEmpty(page.getOutputContentType())) {
+            contentType = page.getOutputContentType() + "; charset=utf-8";
+        } else {
+            String mimeType = RollerContext.getServletContext().getMimeType(
+                    page.getLink());
+            if (mimeType != null) {
+                // we found a match ... set the content deviceType
+                contentType = mimeType + "; charset=utf-8";
+            } else {
+                contentType = "text/html; charset=utf-8";
+            }
+        }
+
+        HashMap model = new HashMap();
+        try {
+            PageContext pageContext = JspFactory.getDefaultFactory()
+                    .getPageContext(this, request, response, "", false, 8192,
+                            true);
+
+            // special hack for menu tag
+            request.setAttribute("pageRequest", pageRequest);
+
+            // populate the rendering model
+            Map initData = new HashMap();
+            initData.put("requestParameters", request.getParameterMap());
+            initData.put("parsedRequest", pageRequest);
+            initData.put("pageContext", pageContext);
+
+            // define url strategy
+            initData.put("urlStrategy", WebloggerFactory.getWeblogger()
+                    .getUrlStrategy());
+
+            // if this was a comment posting, check for comment form
+            WeblogEntryCommentForm commentForm = (WeblogEntryCommentForm) request
+                    .getAttribute("commentForm");
+            if (commentForm != null) {
+                initData.put("commentForm", commentForm);
+            }
+
+            // Load models for pages
+            String pageModels = WebloggerConfig
+                    .getProperty("rendering.pageModels");
+            ModelLoader.loadModels(pageModels, model, initData, true);
+            // Load special models for site-wide blog
+            if (WebloggerRuntimeConfig.isSiteWideWeblog(weblog.getHandle())) {
+                String siteModels = WebloggerConfig
+                        .getProperty("rendering.siteModels");
+                ModelLoader.loadModels(siteModels, model, initData, true);
+            }
+
+            // Load weblog custom models
+            ModelLoader.loadCustomModels(weblog, model, initData);
+
+        } catch (WebloggerException ex) {
+            log.error("Error loading model objects for page", ex);
+
+            if (!response.isCommitted()) {
+                response.reset();
+            }
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            return;
+        }
+
+        // lookup Renderer we are going to use
+        Renderer renderer = null;
+        try {
+            log.debug("Looking up renderer");
+            renderer = RendererManager.getRenderer(page,
+                    pageRequest.getDeviceType());
+        } catch (Exception e) {
+            // nobody wants to render my content :(
+            log.error("Couldn't find renderer for page " + page.getId(), e);
+
+            if (!response.isCommitted()) {
+                response.reset();
+            }
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        // render content. use size of about 24K for a standard page
+        CachedContent rendererOutput = new CachedContent(24567, contentType);
+        try {
+            log.debug("Doing rendering");
+            renderer.render(model, rendererOutput.getCachedWriter());
+
+            // flush rendered output and close
+            rendererOutput.flush();
+            rendererOutput.close();
+        } catch (Exception e) {
+            // bummer, error during rendering
+            log.error("Error during rendering for page " + page.getId(), e);
+
+            if (!response.isCommitted()) {
+                response.reset();
+            }
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
+            return;
+        }
+
+        // post rendering process
+        // flush rendered content to response
+        log.debug("Flushing response output");
+        response.setContentType(contentType);
+        response.setContentLength(rendererOutput.getContent().length);
+        response.getOutputStream().write(rendererOutput.getContent());
+
+        // cache rendered content. only cache if user is not logged in?
+        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn())
+                && request.getAttribute("skipCache") == null) {
+            log.debug("PUT " + cacheKey);
+
+            // put it in the right cache
+            if (isSiteWide) {
+                siteWideCache.put(cacheKey, rendererOutput);
+            } else {
+                weblogPageCache.put(cacheKey, rendererOutput);
+            }
+        } else {
+            log.debug("SKIPPED " + cacheKey);
+        }
+
+        log.debug("Exiting");
+    }
+
+    /**
+     * Handle POST requests.
+     * 
+     * We have this here because the comment servlet actually forwards some of
+     * its requests on to us to render some pages with cusom messaging. We may
+     * want to revisit this approach in the future and see if we can do this in
+     * a different way, but for now this is the easy way.
+     */
+    public void doPost(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+
+        // make sure caching is disabled
+        request.setAttribute("skipCache", "true");
+
+        // handle just like a GET request
+        this.doGet(request, response);
+    }
+
+    /**
+     * Notify the hit tracker that it has an incoming page hit.
+     */
+    private void processHit(Weblog weblog, String url, String referrer) {
+
+        HitCountQueue counter = HitCountQueue.getInstance();
+        counter.processHit(weblog, url, referrer);
+    }
+
+    /**
+     * Process the incoming request to extract referrer info and pass it on to
+     * the referrer processing queue for tracking.
+     * 
+     * @return true if referrer was spam, false otherwise
+     */
+    private boolean processReferrer(HttpServletRequest request) {
+
+        log.debug("processing referrer for " + request.getRequestURI());
+
+        // bleh! because ref processing does a flush it will close
+        // our hibernate session and cause lazy init exceptions on
+        // objects we have fetched, so we need to use a separate
+        // page request object for this
+        WeblogPageRequest pageRequest;
+        try {
+            pageRequest = new WeblogPageRequest(request);
+        } catch (InvalidRequestException ex) {
+            return false;
+        }
+
+        // if this came from site-wide frontpage then skip it
+        if (WebloggerRuntimeConfig.isSiteWideWeblog(pageRequest
+                .getWeblogHandle())) {
+            return false;
+        }
+
+        // if this came from a robot then don't process it
+        if (robotPattern != null) {
+            String userAgent = request.getHeader("User-Agent");
+            if (userAgent != null && userAgent.length() > 0
+                    && robotPattern.matcher(userAgent).matches()) {
+                log.debug("skipping referrer from robot");
+                return false;
+            }
+        }
+
+        String referrerUrl = request.getHeader("Referer");
+        StringBuffer reqsb = request.getRequestURL();
+        if (request.getQueryString() != null) {
+            reqsb.append("?");
+            reqsb.append(request.getQueryString());
+        }
+        String requestUrl = reqsb.toString();
+
+        log.debug("referrer = " + referrerUrl);
+
+        // if this came from persons own blog then don't process it
+        String selfSiteFragment = "/" + pageRequest.getWeblogHandle();
+        if (referrerUrl != null && referrerUrl.contains(selfSiteFragment)) {
+            log.debug("skipping referrer from own blog");
+            return false;
+        }
+
+        // validate the referrer
+        if (pageRequest != null && pageRequest.getWeblogHandle() != null) {
+
+            // Base page URLs, with and without www.
+            String basePageUrlWWW = WebloggerRuntimeConfig
+                    .getAbsoluteContextURL()
+                    + "/"
+                    + pageRequest.getWeblogHandle();
+            String basePageUrl = basePageUrlWWW;
+            if (basePageUrlWWW.startsWith("http://www.")) {
+                // chop off the http://www.
+                basePageUrl = "http://" + basePageUrlWWW.substring(11);
+            }
+
+            // ignore referrers coming from users own blog
+            if (referrerUrl == null
+                    || (!referrerUrl.startsWith(basePageUrl) && !referrerUrl
+                            .startsWith(basePageUrlWWW))) {
+
+                // validate the referrer
+                if (referrerUrl != null) {
+                    // treat editor referral as direct
+                    int lastSlash = requestUrl.indexOf('/', 8);
+                    if (lastSlash == -1) {
+                        lastSlash = requestUrl.length();
+                    }
+                    String requestSite = requestUrl.substring(0, lastSlash);
+
+                    if (referrerUrl.matches(requestSite + ".*\\.rol.*")) {
+                        referrerUrl = null;
+                    } else if (BlacklistChecker.checkReferrer(
+                            pageRequest.getWeblog(), referrerUrl)) {
+                        return true;
+                    }
+                }
+            } else {
+                log.debug("Ignoring referer = " + referrerUrl);
+                return false;
+            }
+        }
+
+        // referrer is valid, lets record it
+        try {
+            IncomingReferrer referrer = new IncomingReferrer();
+            referrer.setReferrerUrl(referrerUrl);
+            referrer.setRequestUrl(requestUrl);
+            referrer.setWeblogHandle(pageRequest.getWeblogHandle());
+            referrer.setWeblogAnchor(pageRequest.getWeblogAnchor());
+            referrer.setWeblogDateString(pageRequest.getWeblogDate());
+
+            ReferrerQueueManager refQueue = WebloggerFactory.getWeblogger()
+                    .getReferrerQueueManager();
+            refQueue.processReferrer(referrer);
+        } catch (Exception e) {
+            log.error("Error processing referrer", e);
+        }
 
-		return false;
-	}
+        return false;
+    }
 }

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewResourceServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewResourceServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewResourceServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewResourceServlet.java Sun Dec  1 14:39:51 2013
@@ -41,99 +41,99 @@ import org.apache.roller.weblogger.pojos
 import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
 import org.apache.roller.weblogger.ui.rendering.util.WeblogPreviewResourceRequest;
 
-
 /**
- * Special previewing servlet which serves files uploaded by users as well as 
- * static resources in shared themes.  This servlet differs from the normal
+ * Special previewing servlet which serves files uploaded by users as well as
+ * static resources in shared themes. This servlet differs from the normal
  * ResourceServlet because it can accept urls parameters which affect how it
  * behaves which are used for previewing.
  */
 public class PreviewResourceServlet extends HttpServlet {
 
     private static Log log = LogFactory.getLog(PreviewResourceServlet.class);
-    
-    private ServletContext context = null;
 
+    private ServletContext context = null;
 
     public void init(ServletConfig config) throws ServletException {
 
         super.init(config);
 
         log.info("Initializing PreviewResourceServlet");
-        
+
         this.context = config.getServletContext();
     }
 
-
     /**
      * Handles requests for user uploaded resources.
      */
     public void doGet(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
-        
+
         Weblog weblog = null;
         String ctx = request.getContextPath();
         String servlet = request.getServletPath();
         String reqURI = request.getRequestURI();
-        
+
         WeblogPreviewResourceRequest resourceRequest = null;
         try {
             // parse the incoming request and extract the relevant data
             resourceRequest = new WeblogPreviewResourceRequest(request);
 
             weblog = resourceRequest.getWeblog();
-            if(weblog == null) {
-                throw new WebloggerException("unable to lookup weblog: "+
-                        resourceRequest.getWeblogHandle());
+            if (weblog == null) {
+                throw new WebloggerException("unable to lookup weblog: "
+                        + resourceRequest.getWeblogHandle());
             }
 
-        } catch(Exception e) {
+        } catch (Exception e) {
             // invalid resource request or weblog doesn't exist
             log.debug("error creating weblog resource request", e);
             response.sendError(HttpServletResponse.SC_NOT_FOUND);
             return;
         }
-        
-        log.debug("Resource requested ["+resourceRequest.getResourcePath()+"]");
-        
+
+        log.debug("Resource requested [" + resourceRequest.getResourcePath()
+                + "]");
+
         long resourceLastMod = 0;
         InputStream resourceStream = null;
-        
+
         // first, see if we have a preview theme to operate from
-        if(!StringUtils.isEmpty(resourceRequest.getThemeName())) {
+        if (!StringUtils.isEmpty(resourceRequest.getThemeName())) {
             Theme theme = resourceRequest.getTheme();
-            ThemeResource resource = theme.getResource(resourceRequest.getResourcePath());
-            if(resource != null) {
+            ThemeResource resource = theme.getResource(resourceRequest
+                    .getResourcePath());
+            if (resource != null) {
                 resourceLastMod = resource.getLastModified();
                 resourceStream = resource.getInputStream();
             }
         }
-        
+
         // second, see if resource comes from weblog's configured shared theme
-        if(resourceStream == null) {
+        if (resourceStream == null) {
             try {
                 WeblogTheme weblogTheme = weblog.getTheme();
-                if(weblogTheme != null) {
-                    ThemeResource resource = weblogTheme.getResource(resourceRequest.getResourcePath());
-                    if(resource != null) {
+                if (weblogTheme != null) {
+                    ThemeResource resource = weblogTheme
+                            .getResource(resourceRequest.getResourcePath());
+                    if (resource != null) {
                         resourceLastMod = resource.getLastModified();
                         resourceStream = resource.getInputStream();
                     }
                 }
             } catch (Exception ex) {
-                // hmmm, some kind of error getting theme.  that's an error.
+                // hmmm, some kind of error getting theme. that's an error.
                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                 return;
             }
         }
-        
+
         // if not from theme then see if resource is in weblog's upload dir
-        if(resourceStream == null) {
+        if (resourceStream == null) {
             try {
-                MediaFileManager mmgr =
-                    WebloggerFactory.getWeblogger().getMediaFileManager();
-                MediaFile mf = mmgr.getMediaFileByOriginalPath(
-                    weblog, resourceRequest.getResourcePath());
+                MediaFileManager mmgr = WebloggerFactory.getWeblogger()
+                        .getMediaFileManager();
+                MediaFile mf = mmgr.getMediaFileByOriginalPath(weblog,
+                        resourceRequest.getResourcePath());
                 resourceLastMod = mf.getLastModified();
                 resourceStream = mf.getInputStream();
 
@@ -144,36 +144,38 @@ public class PreviewResourceServlet exte
                 return;
             }
         }
-        
+
         // Respond with 304 Not Modified if it is not modified.
-        if (ModDateHeaderUtil.respondIfNotModified(request, response, resourceLastMod)) {
+        if (ModDateHeaderUtil.respondIfNotModified(request, response,
+                resourceLastMod, resourceRequest.getDeviceType())) {
             return;
         } else {
             // set last-modified date
-            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod);
+            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod,
+                    resourceRequest.getDeviceType());
         }
-        
 
         // set the content type based on whatever is in our web.xml mime defs
-        response.setContentType(this.context.getMimeType(resourceRequest.getResourcePath()));
-        
+        response.setContentType(this.context.getMimeType(resourceRequest
+                .getResourcePath()));
+
         OutputStream out = null;
         try {
             // ok, lets serve up the file
             byte[] buf = new byte[8192];
             int length = 0;
             out = response.getOutputStream();
-            while((length = resourceStream.read(buf)) > 0) {
+            while ((length = resourceStream.read(buf)) > 0) {
                 out.write(buf, 0, length);
             }
-            
+
             // cleanup
             out.close();
             resourceStream.close();
-            
+
         } catch (Exception ex) {
             log.error("Error writing resource file", ex);
-            if(!response.isCommitted()) {
+            if (!response.isCommitted()) {
                 response.reset();
                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             }

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewServlet.java Sun Dec  1 14:39:51 2013
@@ -156,7 +156,9 @@ public class PreviewServlet extends Http
             // if we don't have a custom tags page then 404, we don't let
             // this one fall through to the default template
             if(page == null) {
-                if(!response.isCommitted()) response.reset();
+                if (!response.isCommitted()) {
+                    response.reset();
+                }
                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
                 return;
             }

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewThemeImageServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewThemeImageServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewThemeImageServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PreviewThemeImageServlet.java Sun Dec  1 14:39:51 2013
@@ -96,11 +96,11 @@ public class PreviewThemeImageServlet ex
         }
         
         // Respond with 304 Not Modified if it is not modified.
-        if (ModDateHeaderUtil.respondIfNotModified(request, response, resourceLastMod)) {
+        if (ModDateHeaderUtil.respondIfNotModified(request, response, resourceLastMod, null)) {
             return;
         } else {
             // set last-modified date
-            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod);
+            ModDateHeaderUtil.setLastModifiedHeader(response, resourceLastMod, null);
         }
         
         log.debug("Everything is cool, sending image");

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java Sun Dec  1 14:39:51 2013
@@ -57,6 +57,9 @@ import org.apache.roller.weblogger.util.
  * Handles search queries for weblogs.
  */
 public class SearchServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 6246730804167411636L;
+
     private static Log log = LogFactory.getLog(SearchServlet.class);
 
     // Development theme reloading
@@ -104,6 +107,33 @@ public class SearchServlet extends HttpS
             return;
         }
 
+        // Development only. Reload if theme has been modified
+        if (themeReload
+                && !weblog.getEditorTheme()
+                        .equals(WeblogTemplate.ACTION_CUSTOM)
+                && (searchRequest.getPathInfo() == null || searchRequest
+                        .getPathInfo() != null)) {
+
+            try {
+                ThemeManager manager = WebloggerFactory.getWeblogger()
+                        .getThemeManager();
+                boolean reloaded = manager.reLoadThemeFromDisk(weblog
+                        .getEditorTheme());
+                if (reloaded) {
+                    if (WebloggerRuntimeConfig.isSiteWideWeblog(searchRequest
+                            .getWeblogHandle())) {
+                        SiteWideCache.getInstance().clear();
+                    } else {
+                        WeblogPageCache.getInstance().clear();
+                    }
+                    I18nMessages.reloadBundle(weblog.getLocaleInstance());
+                }
+
+            } catch (Exception ex) {
+                log.error("ERROR - reloading theme " + ex);
+            }
+        }
+
         // Get the deviceType from user agent
         MobileDeviceRepository.DeviceType deviceType = MobileDeviceRepository
                 .getRequestType(request);
@@ -193,6 +223,7 @@ public class SearchServlet extends HttpS
             // Load weblog custom models
             ModelLoader.loadCustomModels(weblog, model, initData);
 
+            // TODO This causes another search, remove.
             // manually add search model again to support pre-3.0 weblogs
             Model searchModel = new SearchResultsModel();
             searchModel.init(initData);
@@ -208,33 +239,6 @@ public class SearchServlet extends HttpS
             return;
         }
 
-        // Development only. Reload if theme has been modified
-        if (themeReload
-                && !weblog.getEditorTheme()
-                        .equals(WeblogTemplate.ACTION_CUSTOM)
-                && (searchRequest.getPathInfo() == null || searchRequest
-                        .getPathInfo() != null)) {
-
-            try {
-                ThemeManager manager = WebloggerFactory.getWeblogger()
-                        .getThemeManager();
-                boolean reloaded = manager.reLoadThemeFromDisk(weblog
-                        .getEditorTheme());
-                if (reloaded) {
-                    if (WebloggerRuntimeConfig.isSiteWideWeblog(searchRequest
-                            .getWeblogHandle())) {
-                        SiteWideCache.getInstance().clear();
-                    } else {
-                        WeblogPageCache.getInstance().clear();
-                    }
-                    I18nMessages.reloadBundle(weblog.getLocaleInstance());
-                }
-
-            } catch (Exception ex) {
-                log.error("ERROR - reloading theme " + ex);
-            }
-        }
-
         // lookup Renderer we are going to use
         Renderer renderer = null;
         try {

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/TrackbackServlet.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/TrackbackServlet.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/TrackbackServlet.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/TrackbackServlet.java Sun Dec  1 14:39:51 2013
@@ -223,7 +223,7 @@ public class TrackbackServlet extends Ht
     
     private String getSuccessResponse(String message) {
         
-        StringBuffer output = new StringBuffer();
+        StringBuilder output = new StringBuilder();
         
         output.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
         output.append("<response>");
@@ -239,7 +239,7 @@ public class TrackbackServlet extends Ht
     
     private String getErrorResponse(String message) {
         
-        StringBuffer output = new StringBuffer();
+        StringBuilder output = new StringBuilder();
         
         output.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>");
         output.append("<response>");

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/ModDateHeaderUtil.java Sun Dec  1 14:39:51 2013
@@ -18,76 +18,148 @@
 
 package org.apache.roller.weblogger.ui.rendering.util;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.util.DateUtil;
+import org.apache.roller.weblogger.ui.rendering.mobile.MobileDeviceRepository;
+
 /**
  * Utility class to localize the modification date header-related logic.
  */
 public class ModDateHeaderUtil {
-    private static final Log log = LogFactory.getLog(ModDateHeaderUtil.class);
 
-    // Utility class with static methods; inhibit construction
-    private ModDateHeaderUtil() {
+	private static Log log = LogFactory.getLog(ModDateHeaderUtil.class);
+
+	/**
+	 * Instantiates a new mod date header util.
+	 */
+	private ModDateHeaderUtil() {
+	}
+
+	/**
+	 * Sets the HTTP response status to 304 (NOT MODIFIED) if the request
+	 * contains an If-Modified-Since header that specifies a time that is at or
+	 * after the time specified by the value of lastModifiedTimeMillis
+	 * <em>truncated to second granularity</em>. Returns true if the response
+	 * status was set, false if not.
+	 * 
+	 * @param request
+	 *            the request
+	 * @param response
+	 *            the response
+	 * @param lastModifiedTimeMillis
+	 *            the last modified time millis
+	 * @param deviceType
+	 *            the device type. Null to ignore ie no theme device type
+	 *            swithing check.
+	 * 
+	 * @return true if a response status was sent, false otherwise.
+	 */
+	public static boolean respondIfNotModified(HttpServletRequest request,
+			HttpServletResponse response, long lastModifiedTimeMillis,
+			MobileDeviceRepository.DeviceType deviceType) {
+
+		long sinceDate = 0;
+		try {
+			sinceDate = request.getDateHeader("If-Modified-Since");
+		} catch (IllegalArgumentException ex) {
+			// this indicates there was some problem parsing the header value as
+			// a date
+			return false;
+		}
+
+		// truncate to seconds
+		lastModifiedTimeMillis -= (lastModifiedTimeMillis % 1000);
+
+		if (log.isDebugEnabled()) {
+			SimpleDateFormat dateFormat = new SimpleDateFormat(
+					"EEE MMM dd 'at' h:mm:ss a");
+			log.debug("since date = "
+					+ DateUtil.format(new Date(sinceDate), dateFormat));
+			log.debug("last mod date (trucated to seconds) = "
+					+ DateUtil.format(new Date(lastModifiedTimeMillis),
+							dateFormat));
+		}
+
+		// Set device type for device switching
+		String eTag = null;
+		if (deviceType != null) {
+			// int code = new HashCodeBuilder().append(deviceType.name())
+			// .hashCode();
+			// eTag = String.valueOf(code);
+			eTag = deviceType.name();
+		}
+
+		String previousToken = request.getHeader("If-None-Match");
+		if (eTag != null && previousToken != null && eTag.equals(previousToken)
+				&& lastModifiedTimeMillis <= sinceDate
+				|| (eTag == null || previousToken == null)
+				&& lastModifiedTimeMillis <= sinceDate) {
+
+			if (log.isDebugEnabled()) {
+				log.debug("NOT MODIFIED " + request.getRequestURL());
+            }
+
+			response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+
+			// use the same date we sent when we created the ETag the
+			// first time through
+			response.setHeader("Last-Modified",
+					request.getHeader("If-Modified-Since"));
+
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Set the Last-Modified header using the given time in milliseconds. Note
+	 * that because the header has the granularity of one second, the value will
+	 * get truncated to the nearest second that does not exceed the provided
+	 * value.
+	 * <p/>
+	 * This will also set the Expires header to a date in the past. This forces
+	 * clients to revalidate the cache each time.
+	 * 
+	 * @param response
+	 *            the response
+	 * @param lastModifiedTimeMillis
+	 *            the last modified time millis
+	 * @param deviceType
+	 *            the device type. Null to ignore ie no theme device type
+	 *            swithing check.
+	 */
+	public static void setLastModifiedHeader(HttpServletResponse response,
+			long lastModifiedTimeMillis,
+			MobileDeviceRepository.DeviceType deviceType) {
+
+		// Save our device type for device switching. Must use chaching on
+		// headers for this to work.
+		if (deviceType != null) {
+
+			// int code = new HashCodeBuilder().append(deviceType.name())
+			// .hashCode();
+			// String eTag = String.valueOf(code);
+
+			String eTag = deviceType.name();
+
+			response.setHeader("ETag", eTag);
+		}
+
+		response.setDateHeader("Last-Modified", lastModifiedTimeMillis);
+		// Force clients to revalidate each time
+		// See RFC 2616 (HTTP 1.1 spec) secs 14.21, 13.2.1
+		response.setDateHeader("Expires", 0);
+		// We may also want this (See 13.2.1 and 14.9.4)
+		// response.setHeader("Cache-Control","must-revalidate");
 
-    }
+	}
 
-    /**
-     * Sets the HTTP response status to 304 (NOT MODIFIED) if the request contains an
-     * If-Modified-Since header that specifies a time that is
-     * at or after the time specified by the value of lastModifiedTimeMillis
-     * <em>truncated to second granularity</em>.  Returns true if
-     * the response status was set, false if not.
-     *
-     * @param request
-     * @param response
-     * @param lastModifiedTimeMillis
-     * @return true if a response status was sent, false otherwise.
-     */
-    public static boolean respondIfNotModified(HttpServletRequest request,
-                                               HttpServletResponse response,
-                                               long lastModifiedTimeMillis) {
-        long sinceDate = 0;
-        try {
-            sinceDate = request.getDateHeader("If-Modified-Since");
-        } catch(IllegalArgumentException ex) {
-            // this indicates there was some problem parsing the header value as a date
-            return false;
-        }
-        
-        // truncate to seconds
-        lastModifiedTimeMillis -= (lastModifiedTimeMillis % 1000);
-        log.debug("since date = " + sinceDate);
-        log.debug("last mod date (trucated to seconds) = " + lastModifiedTimeMillis);
-        if (lastModifiedTimeMillis <= sinceDate) {
-            log.debug("NOT MODIFIED " + request.getRequestURL());
-            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Set the Last-Modified header using the given time in milliseconds.  Note that because the
-     * header has the granularity of one second, the value will get truncated to the nearest second that does not
-     * exceed the provided value.
-     * <p/>
-     * This will also set the Expires header to a date in the past.  This forces clients to revalidate the cache each
-     * time.
-     *
-     * @param response
-     * @param lastModifiedTimeMillis
-     */
-    public static void setLastModifiedHeader(HttpServletResponse response, long lastModifiedTimeMillis) {
-        response.setDateHeader("Last-Modified", lastModifiedTimeMillis);
-        // Force clients to revalidate each time
-        // See RFC 2616 (HTTP 1.1 spec) secs 14.21, 13.2.1
-        response.setDateHeader("Expires", 0);
-        // We may also want this (See 13.2.1 and 14.9.4)
-        // response.setHeader("Cache-Control","must-revalidate");
-    }
 }

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/PlanetRequest.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/PlanetRequest.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/PlanetRequest.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/PlanetRequest.java Sun Dec  1 14:39:51 2013
@@ -82,7 +82,7 @@ public class PlanetRequest extends Parse
          *   group - specifies the aggregation group to include
          */
         if (request.getParameter("excerpts") != null) {
-            this.excerpts = Boolean.valueOf(request.getParameter("excerpts")).booleanValue();
+            this.excerpts = Boolean.valueOf(request.getParameter("excerpts"));
         }
         
         if (request.getParameter("group") != null) {

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/PlanetCache.java Sun Dec  1 14:39:51 2013
@@ -191,7 +191,7 @@ public final class PlanetCache {
      */
     public String generateKey(PlanetRequest planetRequest) {
         
-        StringBuffer key = new StringBuffer();
+        StringBuilder key = new StringBuilder();
         
         key.append(this.CACHE_ID).append(":");
         key.append(planetRequest.getContext());

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/SiteWideCache.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/SiteWideCache.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/SiteWideCache.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/SiteWideCache.java Sun Dec  1 14:39:51 2013
@@ -195,7 +195,7 @@ public class SiteWideCache implements Ca
      */
     public String generateKey(WeblogPageRequest pageRequest) {
         
-        StringBuffer key = new StringBuffer();
+        StringBuilder key = new StringBuilder();
         
         key.append(this.CACHE_ID).append(":");
         key.append("page/");
@@ -285,7 +285,7 @@ public class SiteWideCache implements Ca
      */
     public String generateKey(WeblogFeedRequest feedRequest) {
         
-        StringBuffer key = new StringBuffer();
+        StringBuilder key = new StringBuilder();
         
         key.append(this.CACHE_ID).append(":");
         key.append("feed/");
@@ -427,7 +427,7 @@ public class SiteWideCache implements Ca
             return null;
         }
         
-        StringBuffer string = new StringBuffer();
+        StringBuilder string = new StringBuilder();
         
         String key = null;
         String[] value = null;

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogFeedCache.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogFeedCache.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogFeedCache.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogFeedCache.java Sun Dec  1 14:39:51 2013
@@ -162,7 +162,7 @@ public final class WeblogFeedCache {
      */
     public String generateKey(WeblogFeedRequest feedRequest) {
         
-        StringBuffer key = new StringBuffer();
+        StringBuilder key = new StringBuilder();
         
         key.append(this.CACHE_ID).append(":");
         key.append(feedRequest.getWeblogHandle());

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogPageCache.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogPageCache.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogPageCache.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/rendering/util/cache/WeblogPageCache.java Sun Dec  1 14:39:51 2013
@@ -167,7 +167,7 @@ public final class WeblogPageCache {
      */
     public String generateKey(WeblogPageRequest pageRequest) {
         
-        StringBuffer key = new StringBuffer();
+        StringBuilder key = new StringBuilder();
         
         key.append(this.CACHE_ID).append(":");
         key.append(pageRequest.getWeblogHandle());
@@ -249,7 +249,7 @@ public final class WeblogPageCache {
             return null;
         }
         
-        StringBuffer string = new StringBuffer();
+        StringBuilder string = new StringBuilder();
         
         String key = null;
         String[] value = null;

Modified: roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkBean.java
URL: http://svn.apache.org/viewvc/roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkBean.java?rev=1546816&r1=1546815&r2=1546816&view=diff
==============================================================================
--- roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkBean.java (original)
+++ roller/branches/rome2/app/src/main/java/org/apache/roller/weblogger/ui/struts2/editor/BookmarkBean.java Sun Dec  1 14:39:51 2013
@@ -30,8 +30,8 @@ public class BookmarkBean {
     private String name = null;
     private String description = null;
     private String url = null;
-    private Integer weight = new Integer(0);
-    private Integer priority = new Integer(0);
+    private Integer weight = 0;
+    private Integer priority = 0;
     private String image = null;
     private String feedUrl = null;
     



Mime
View raw message