roller-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agillil...@apache.org
Subject svn commit: r423306 - in /incubator/roller/branches/roller_3.0: src/org/apache/roller/ui/rendering/filters/ src/org/apache/roller/ui/rendering/servlets/ src/org/apache/roller/ui/rendering/util/ web/WEB-INF/classes/
Date Wed, 19 Jul 2006 00:15:55 GMT
Author: agilliland
Date: Tue Jul 18 17:15:55 2006
New Revision: 423306

URL: http://svn.apache.org/viewvc?rev=423306&view=rev
Log:
more tweaks to caching for Roller 3.0.

- wrapped rendering caches into their own classes and moved them outside of the servlets.  this minimizes the amount of caching specific code in the servlets and it provides an opportunity for multiple classes to more easily share a rendering cache.

- removed old main page cache filter and added in new site-wide cache which is used by both the page and feed servlets.

- tweaked caching props in roller.properties accordingly.


Added:
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/SiteWideCache.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogFeedCache.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogPageCache.java
Removed:
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/filters/MainPageCacheFilter.java
Modified:
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/filters/PlanetCacheFilter.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/FeedServlet.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PageServlet.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PlanetFeedServlet.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java
    incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/PlanetCache.java
    incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/filters/PlanetCacheFilter.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/filters/PlanetCacheFilter.java?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/filters/PlanetCacheFilter.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/filters/PlanetCacheFilter.java Tue Jul 18 17:15:55 2006
@@ -51,6 +51,20 @@
     
     
     /**
+     * Init method for this filter
+     */
+    public void init(FilterConfig filterConfig) {
+        
+        log.info("Initializing planet cache filter");
+        
+        this.excludeOwnerPages = 
+                RollerConfig.getBooleanProperty("cache.excludeOwnerEditPages");
+        
+        this.planetCache = PlanetCache.getInstance();
+    }
+    
+    
+    /**
      * Process filter.
      */
     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
@@ -66,13 +80,12 @@
             planetRequest = new PlanetRequest(request);
         } catch(Exception e) {
             // some kind of error parsing the request
-            log.error("error creating planet request", e);
+            log.debug("error creating planet request", e);
             response.sendError(HttpServletResponse.SC_NOT_FOUND);
             return;
         }
         
-        String key = "planetCache:"+this.generateKey(planetRequest);
-        
+        String key = planetCache.generateKey(planetRequest);
         try {
             ResponseContent respContent = null;
             if(!this.excludeOwnerPages || !planetRequest.isLoggedIn()) {
@@ -131,68 +144,8 @@
     
     
     /**
-     * Generate a cache key from a parsed planet request.
-     * This generates a key of the form ...
-     *
-     * <context>/<type>/<language>[/user]
-     *   or
-     * <context>/<type>[/flavor]/<language>[/excerpts]
-     *
-     *
-     * examples ...
-     *
-     * planet/page/en
-     * planet/feed/rss/en/excerpts
-     *
-     */
-    private String generateKey(PlanetRequest planetRequest) {
-        
-        StringBuffer key = new StringBuffer();
-        key.append(planetRequest.getContext());
-        key.append("/");
-        key.append(planetRequest.getType());
-        
-        if(planetRequest.getFlavor() != null) {
-            key.append("/").append(planetRequest.getFlavor());
-        }
-        
-        // add language
-        key.append("/").append(planetRequest.getLanguage());
-        
-        if(planetRequest.getFlavor() != null) {
-            // add excerpts
-            if(planetRequest.isExcerpts()) {
-                key.append("/excerpts");
-            }
-        } else {
-            // add login state
-            if(planetRequest.getAuthenticUser() != null) {
-                key.append("/user=").append(planetRequest.getAuthenticUser());
-            }
-        }
-        
-        return key.toString();
-    }
-    
-    
-    /**
      * Destroy method for this filter
      */
-    public void destroy() {
-    }
-    
-    
-    /**
-     * Init method for this filter
-     */
-    public void init(FilterConfig filterConfig) {
-        
-        log.info("Initializing planet cache");
-        
-        this.excludeOwnerPages = 
-                RollerConfig.getBooleanProperty("cache.planet.excludeOwnerEditPages");
-        
-        this.planetCache = PlanetCache.getInstance();
-    }
+    public void destroy() {}
     
 }

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/FeedServlet.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/FeedServlet.java?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/FeedServlet.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/FeedServlet.java Tue Jul 18 17:15:55 2006
@@ -21,8 +21,6 @@
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLEncoder;
-import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 import javax.servlet.ServletConfig;
@@ -33,29 +31,15 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.roller.RollerException;
-import org.apache.roller.config.RollerConfig;
 import org.apache.roller.config.RollerRuntimeConfig;
-import org.apache.roller.model.RollerFactory;
-import org.apache.roller.model.UserManager;
-import org.apache.roller.pojos.BookmarkData;
-import org.apache.roller.pojos.CommentData;
-import org.apache.roller.pojos.FolderData;
-import org.apache.roller.pojos.RefererData;
-import org.apache.roller.pojos.UserData;
-import org.apache.roller.pojos.WeblogCategoryData;
-import org.apache.roller.pojos.WeblogEntryData;
-import org.apache.roller.pojos.WeblogTemplate;
 import org.apache.roller.pojos.WebsiteData;
-import org.apache.roller.ui.core.RollerContext;
 import org.apache.roller.ui.rendering.util.WeblogFeedRequest;
 import org.apache.roller.util.cache.CachedContent;
 import org.apache.roller.ui.rendering.Renderer;
 import org.apache.roller.ui.rendering.RendererManager;
 import org.apache.roller.ui.rendering.model.ModelLoader;
-import org.apache.roller.util.cache.Cache;
-import org.apache.roller.util.cache.CacheHandler;
-import org.apache.roller.util.cache.CacheManager;
-import org.apache.roller.util.cache.LazyExpiringCacheEntry;
+import org.apache.roller.ui.rendering.util.SiteWideCache;
+import org.apache.roller.ui.rendering.util.WeblogFeedCache;
 
 
 /**
@@ -68,11 +52,8 @@
     
     private static Log log = LogFactory.getLog(FeedServlet.class);
     
-    // a unique identifier for our cache, this is used as the prefix for
-    // roller config properties that apply to this cache
-    private static final String CACHE_ID = "cache.feed";
-    
-    private Cache contentCache = null;
+    private WeblogFeedCache weblogFeedCache = null;
+    private SiteWideCache siteWideCache = null;
     
     
     /**
@@ -84,23 +65,11 @@
         
         log.info("Initializing FeedServlet");
         
-        Map cacheProps = new HashMap();
-        cacheProps.put("id", CACHE_ID);
-        Enumeration allProps = RollerConfig.keys();
-        String prop = null;
-        while(allProps.hasMoreElements()) {
-            prop = (String) allProps.nextElement();
-            
-            // we are only interested in props for this cache
-            if(prop.startsWith(CACHE_ID+".")) {
-                cacheProps.put(prop.substring(CACHE_ID.length()+1), 
-                        RollerConfig.getProperty(prop));
-            }
-        }
-        
-        log.info("Feed cache = "+cacheProps);
+        // get a reference to the weblog feed cache
+        this.weblogFeedCache = WeblogFeedCache.getInstance();
         
-        contentCache = CacheManager.constructCache(null, cacheProps);
+        // get a reference to the site wide cache
+        this.siteWideCache = SiteWideCache.getInstance();
     }
     
     
@@ -113,6 +82,7 @@
         log.debug("Entering");
         
         WebsiteData weblog = null;
+        boolean isSiteWide = false;
         
         WeblogFeedRequest feedRequest = null;
         try {
@@ -124,6 +94,10 @@
                 throw new RollerException("unable to lookup weblog: "+
                         feedRequest.getWeblogHandle());
             }
+            
+            // is this the site-wide weblog?
+            isSiteWide = RollerRuntimeConfig.isSiteWideWeblog(feedRequest.getWeblogHandle());
+            
         } catch(Exception e) {
             // invalid feed request format or weblog doesn't exist
             log.debug("error creating weblog feed request", e);
@@ -132,41 +106,26 @@
         }
             
         
+        // determine the lastModified date for this content
+        long lastModified = 0;
+        if(isSiteWide) {
+            lastModified = siteWideCache.getLastModified().getTime();
+        } else {
+            lastModified = weblog.getLastModified().getTime();
+        }
+        
         // 304 if-modified-since checking
         long sinceDate = request.getDateHeader("If-Modified-Since");
         log.debug("since date = "+sinceDate);
-        if(weblog.getLastModified().getTime() <= sinceDate) {
+        if(lastModified <= sinceDate) {
             log.debug("NOT MODIFIED "+request.getRequestURL());
             response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
             return;
         }
         
         // set last-modified date
-        response.setDateHeader("Last-Modified", weblog.getLastModified().getTime());
+        response.setDateHeader("Last-Modified", lastModified);
         
-        // cached content checking
-        String cacheKey = this.CACHE_ID+":"+this.generateKey(feedRequest);
-        LazyExpiringCacheEntry entry =
-                (LazyExpiringCacheEntry) this.contentCache.get(cacheKey);
-        if(entry != null) {
-            CachedContent cachedContent = 
-                    (CachedContent) entry.getValue(weblog.getLastModified().getTime());
-            
-            if(cachedContent != null) {
-                log.debug("HIT "+cacheKey);
-                
-                response.setContentLength(cachedContent.getContent().length);
-                response.getOutputStream().write(cachedContent.getContent());
-                return;
-                
-            } else {
-                log.debug("HIT-EXPIRED "+cacheKey);
-            }
-            
-        } else {
-            log.debug("MISS "+cacheKey);
-        }
-
         // set content type
         if("rss".equals(feedRequest.getFormat())) {
             response.setContentType("application/rss+xml; charset=utf-8");
@@ -174,6 +133,35 @@
             response.setContentType("application/atom+xml; charset=utf-8");
         }
         
+        
+        // generate cache key
+        String cacheKey = null;
+        if(isSiteWide) {
+            cacheKey = siteWideCache.generateKey(feedRequest);
+        } else {
+            cacheKey = weblogFeedCache.generateKey(feedRequest);
+        }
+        
+        // cached content checking
+        CachedContent cachedContent = null;
+        if(isSiteWide) {
+            cachedContent = (CachedContent) siteWideCache.get(cacheKey);
+        } else {
+            cachedContent = (CachedContent) weblogFeedCache.get(cacheKey, lastModified);
+        }
+        
+        if(cachedContent != null) {
+            log.debug("HIT "+cacheKey);
+            
+            response.setContentLength(cachedContent.getContent().length);
+            response.getOutputStream().write(cachedContent.getContent());
+            return;
+            
+        } else {
+            log.debug("MISS "+cacheKey);
+        }
+        
+        
         // looks like we need to render content
         HashMap model = new HashMap();
         String pageId = null;
@@ -255,53 +243,13 @@
         
         // cache rendered content.  only cache if user is not logged in?
         log.debug("PUT "+cacheKey);
-        this.contentCache.put(cacheKey, new LazyExpiringCacheEntry(rendererOutput));
-        
-        log.debug("Exiting");
-    }
-
-    
-    /**
-     * Generate a cache key from a parsed weblog feed request.
-     * This generates a key of the form ...
-     *
-     * <context>[/handle]/<flavor>[/category]/<language>[/excerpts]
-     *
-     * examples ...
-     *
-     * main/rss/en
-     * weblog/foo/rss/MyCategory/en
-     * weblog/foo/atom/en/excerpts
-     *
-     */
-    private String generateKey(WeblogFeedRequest feedRequest) {
-        
-        StringBuffer key = new StringBuffer();
-        
-        key.append("weblog");
-        key.append("/").append(feedRequest.getWeblogHandle().toLowerCase());
-        key.append("/").append(feedRequest.getType());
-        key.append("/").append(feedRequest.getFormat());
-        
-        if(feedRequest.getWeblogCategoryName() != null) {
-            String cat = feedRequest.getWeblogCategoryName();
-            try {
-                cat = URLEncoder.encode(cat, "UTF-8");
-            } catch (UnsupportedEncodingException ex) {
-                // should never happen, utf-8 is always supported
-            }
-            
-            key.append("/").append(cat);
-        }
-        
-        // add locale
-        key.append("/").append(feedRequest.getLocale());
-        
-        if(feedRequest.isExcerpts()) {
-            key.append("/excerpts");
+        if(isSiteWide) {
+            siteWideCache.put(cacheKey, rendererOutput);
+        } else {
+            weblogFeedCache.put(cacheKey, rendererOutput);
         }
         
-        return key.toString();
+        log.debug("Exiting");
     }
     
 }

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PageServlet.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PageServlet.java?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PageServlet.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PageServlet.java Tue Jul 18 17:15:55 2006
@@ -20,7 +20,6 @@
 
 import java.io.IOException;
 import java.util.Date;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
 import javax.servlet.ServletConfig;
@@ -35,14 +34,7 @@
 import org.apache.roller.RollerException;
 import org.apache.roller.config.RollerConfig;
 import org.apache.roller.config.RollerRuntimeConfig;
-import org.apache.roller.pojos.BookmarkData;
-import org.apache.roller.pojos.CommentData;
-import org.apache.roller.pojos.FolderData;
-import org.apache.roller.pojos.RefererData;
 import org.apache.roller.pojos.Template;
-import org.apache.roller.pojos.UserData;
-import org.apache.roller.pojos.WeblogCategoryData;
-import org.apache.roller.pojos.WeblogEntryData;
 import org.apache.roller.pojos.WeblogTemplate;
 import org.apache.roller.pojos.WebsiteData;
 import org.apache.roller.ui.core.RollerContext;
@@ -51,29 +43,25 @@
 import org.apache.roller.ui.rendering.Renderer;
 import org.apache.roller.ui.rendering.RendererManager;
 import org.apache.roller.ui.rendering.model.ModelLoader;
-import org.apache.roller.util.Utilities;
-import org.apache.roller.util.cache.Cache;
-import org.apache.roller.util.cache.CacheHandler;
-import org.apache.roller.util.cache.CacheManager;
-import org.apache.roller.util.cache.LazyExpiringCacheEntry;
+import org.apache.roller.ui.rendering.util.SiteWideCache;
+import org.apache.roller.ui.rendering.util.WeblogPageCache;
+
  
 
 /**
- * Responsible for rendering weblog pages.
+ * Provides access to weblog pages.
  *
  * @web.servlet name="PageServlet" load-on-startup="5"
  * @web.servlet-mapping url-pattern="/roller-ui/rendering/page/*"
  */
-public class PageServlet extends HttpServlet implements CacheHandler {
+public class PageServlet extends HttpServlet {
     
     private static Log log = LogFactory.getLog(PageServlet.class);
     
-    // a unique identifier for our cache, this is used as the prefix for
-    // roller config properties that apply to this cache
-    private static final String CACHE_ID = "cache.weblogpage";
-    
     private boolean excludeOwnerPages = false;
-    private Cache contentCache = null;
+    
+    private WeblogPageCache weblogPageCache = null;
+    private SiteWideCache siteWideCache = null;
     
     
     /**
@@ -86,25 +74,13 @@
         log.info("Initializing PageServlet");
         
         this.excludeOwnerPages = 
-                RollerConfig.getBooleanProperty(this.CACHE_ID+".excludeOwnerEditPages");
-        
-        Map cacheProps = new HashMap();
-        cacheProps.put("id", CACHE_ID);
-        Enumeration allProps = RollerConfig.keys();
-        String prop = null;
-        while(allProps.hasMoreElements()) {
-            prop = (String) allProps.nextElement();
-            
-            // we are only interested in props for this cache
-            if(prop.startsWith(CACHE_ID+".")) {
-                cacheProps.put(prop.substring(CACHE_ID.length()+1), 
-                        RollerConfig.getProperty(prop));
-            }
-        }
+                RollerConfig.getBooleanProperty("cache.excludeOwnerEditPages");
         
-        log.info("Page cache = "+cacheProps);
+        // get a reference to the weblog page cache
+        this.weblogPageCache = WeblogPageCache.getInstance();
         
-        contentCache = CacheManager.constructCache(this, cacheProps);
+        // get a reference to the site wide cache
+        this.siteWideCache = SiteWideCache.getInstance();
     }
     
     
@@ -117,6 +93,7 @@
         log.debug("Entering");
         
         WebsiteData weblog = null;
+        boolean isSiteWide = false;
         
         WeblogPageRequest pageRequest = null;
         try {
@@ -127,6 +104,10 @@
                 throw new RollerException("unable to lookup weblog: "+
                         pageRequest.getWeblogHandle());
             }
+            
+            // is this the site-wide weblog?
+            isSiteWide = RollerRuntimeConfig.isSiteWideWeblog(pageRequest.getWeblogHandle());
+            
         } catch (Exception e) {
             // some kind of error parsing the request or looking up weblog
             log.debug("error creating page request", e);
@@ -135,15 +116,26 @@
         }
         
         
+        // determine the lastModified date for this content
+        long lastModified = 0;
+        if(isSiteWide) {
+            lastModified = siteWideCache.getLastModified().getTime();
+        } else {
+            lastModified = weblog.getLastModified().getTime();
+        }
+        
         // 304 if-modified-since checking
         long sinceDate = request.getDateHeader("If-Modified-Since");
         log.debug("since date = "+sinceDate);
-        if(weblog.getLastModified().getTime() <= sinceDate) {
+        if(lastModified <= sinceDate) {
             log.debug("NOT MODIFIED "+request.getRequestURL());
             response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
             return;
         }
         
+        // set last-modified date
+        response.setDateHeader("Last-Modified", lastModified);
+        
         
         // set the content type
         String pageLink = pageRequest.getWeblogPageName();
@@ -155,31 +147,32 @@
             response.setContentType("text/html; charset=utf-8");
         }
         
-        // set last-modified date
-        response.setDateHeader("Last-Modified", weblog.getLastModified().getTime());
         
+        // generate cache key
+        String cacheKey = null;
+        if(isSiteWide) {
+            cacheKey = siteWideCache.generateKey(pageRequest);
+        } else {
+            cacheKey = weblogPageCache.generateKey(pageRequest);
+        }
         
         // cached content checking
-        String cacheKey = this.CACHE_ID+":"+this.generateKey(pageRequest);
         if((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) &&
                 request.getAttribute("skipCache") == null) {
             
-            LazyExpiringCacheEntry entry =
-                    (LazyExpiringCacheEntry) this.contentCache.get(cacheKey);
-            if(entry != null) {
-                CachedContent cachedContent = 
-                        (CachedContent) entry.getValue(weblog.getLastModified().getTime());
+            CachedContent cachedContent = null;
+            if(isSiteWide) {
+                cachedContent = (CachedContent) siteWideCache.get(cacheKey);
+            } else {
+                cachedContent = (CachedContent) weblogPageCache.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("HIT-EXPIRED "+cacheKey);
-                }
+                response.setContentLength(cachedContent.getContent().length);
+                response.getOutputStream().write(cachedContent.getContent());
+                return;
                 
             } else {
                 log.debug("MISS "+cacheKey);
@@ -285,7 +278,7 @@
             ModelLoader.loadPageModels(model, initData);
             
             // special handling for site wide weblog
-            if (RollerRuntimeConfig.isSiteWideWeblog(weblog.getHandle())) {
+            if(isSiteWide) {
                 ModelLoader.loadSiteModels(model, initData);
             }
             
@@ -322,7 +315,7 @@
             return;
         }
         
-        // render content.  use default size of about 24K for a standard page
+        // render content.  use size of about 24K for a standard page
         CachedContent rendererOutput = new CachedContent(24567);
         try {
             log.debug("Doing rendering");
@@ -352,7 +345,13 @@
         if((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) &&
                 request.getAttribute("skipCache") == null) {
             log.debug("PUT "+cacheKey);
-            this.contentCache.put(cacheKey, new LazyExpiringCacheEntry(rendererOutput));
+            
+            // put it in the right cache
+            if(isSiteWide) {
+                siteWideCache.put(cacheKey, rendererOutput);
+            } else {
+                weblogPageCache.put(cacheKey, rendererOutput);
+            }
         } else {
             log.debug("SKIPPED "+cacheKey);
         }
@@ -377,133 +376,6 @@
         
         // handle just like a GET request
         this.doGet(request, response);
-    }
-    
-    
-    /**
-     * Generate a cache key from a parsed weblog page request.
-     * This generates a key of the form ...
-     *
-     * weblog/<handle>/page/<type>[/anchor]/<weblogPage>/<language>[/user]
-     *   or
-     * weblog/<handle>/page/<type>[/date][/category]/<weblogPage>/<language>[/user]
-     *
-     *
-     * examples ...
-     *
-     * weblog/foo/page/main/Weblog/en
-     * weblog/foo/page/permalink/entry_anchor/Weblog/en
-     * weblog/foo/page/archive/20051110/Weblog/en
-     * weblog/foo/page/archive/MyCategory/Weblog/en/user=myname
-     *
-     */
-    private String generateKey(WeblogPageRequest pageRequest) {
-        
-        StringBuffer key = new StringBuffer();
-        key.append("weblog/page/");
-        key.append(pageRequest.getWeblogHandle().toLowerCase());
-        key.append("/").append(pageRequest.getContext());
-        
-        if(pageRequest.getWeblogAnchor() != null) {
-            // convert to base64 because there can be spaces in anchors :/
-            key.append("/").append(Utilities.toBase64(pageRequest.getWeblogAnchor().getBytes()));
-        } else {
-            
-            if(pageRequest.getWeblogDate() != null) {
-                key.append("/").append(pageRequest.getWeblogDate());
-            }
-            
-            if(pageRequest.getWeblogCategoryName() != null) {
-                String cat = pageRequest.getWeblogCategoryName();
-                if(cat.startsWith("/")) {
-                    cat = cat.substring(1);
-                }
-
-                // categories may contain spaces, which is not desired
-                key.append("/").append(org.apache.commons.lang.StringUtils.deleteWhitespace(cat));
-            }
-        }
-        
-        // add page name
-        key.append("/").append(pageRequest.getWeblogPageName());
-        
-        // add locale
-        key.append("/").append(pageRequest.getLocale());
-        
-        // add page number when applicable
-        if(pageRequest.getWeblogAnchor() == null) {
-            key.append("/page=").append(pageRequest.getPageNum());
-        }
-        
-        // add login state
-        if(pageRequest.getAuthenticUser() != null) {
-            key.append("/user=").append(pageRequest.getAuthenticUser());
-        }
-        
-        return key.toString();
-    }
-    
-    
-    /**
-     * A weblog entry has changed.
-     */
-    public void invalidate(WeblogEntryData entry) {
-    }
-    
-    
-    /**
-     * A weblog has changed.
-     */
-    public void invalidate(WebsiteData website) {
-    }
-    
-    
-    /**
-     * A bookmark has changed.
-     */
-    public void invalidate(BookmarkData bookmark) {
-    }
-    
-    
-    /**
-     * A folder has changed.
-     */
-    public void invalidate(FolderData folder) {
-    }
-    
-    
-    /**
-     * A comment has changed.
-     */
-    public void invalidate(CommentData comment) {
-    }
-    
-    
-    /**
-     * A referer has changed.
-     */
-    public void invalidate(RefererData referer) {
-    }
-    
-    
-    /**
-     * A user profile has changed.
-     */
-    public void invalidate(UserData user) {
-    }
-    
-    
-    /**
-     * A category has changed.
-     */
-    public void invalidate(WeblogCategoryData category) {
-    }
-    
-    
-    /**
-     * A weblog template has changed.
-     */
-    public void invalidate(WeblogTemplate template) {
     }
     
 }

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PlanetFeedServlet.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PlanetFeedServlet.java?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PlanetFeedServlet.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PlanetFeedServlet.java Tue Jul 18 17:15:55 2006
@@ -95,7 +95,7 @@
         }
         
         // figure planet last modified date
-        Date lastModified = planetCache.lastModified();
+        Date lastModified = planetCache.getLastModified();
         
         // 304 if-modified-since checking
         long sinceDate = request.getDateHeader("If-Modified-Since");

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/servlets/PreviewServlet.java Tue Jul 18 17:15:55 2006
@@ -214,16 +214,4 @@
         log.debug("Exiting");
     }
     
-    
-    /**
-     * Handle POST requests.
-     *
-     * Post requests are not allowed, send a 404.
-     */
-    public void doPost(HttpServletRequest request, HttpServletResponse response)
-            throws ServletException, IOException {
-        
-        response.sendError(HttpServletResponse.SC_NOT_FOUND);
-    }
-    
 }

Modified: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/PlanetCache.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/PlanetCache.java?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/PlanetCache.java (original)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/PlanetCache.java Tue Jul 18 17:15:55 2006
@@ -27,27 +27,15 @@
 import org.apache.roller.RollerException;
 import org.apache.roller.config.RollerConfig;
 import org.apache.roller.model.RollerFactory;
-import org.apache.roller.pojos.BookmarkData;
-import org.apache.roller.pojos.CommentData;
-import org.apache.roller.pojos.FolderData;
-import org.apache.roller.pojos.RefererData;
-import org.apache.roller.pojos.UserData;
-import org.apache.roller.pojos.WeblogCategoryData;
-import org.apache.roller.pojos.WeblogEntryData;
-import org.apache.roller.pojos.WeblogTemplate;
-import org.apache.roller.pojos.WebsiteData;
 import org.apache.roller.util.cache.Cache;
-import org.apache.roller.util.cache.CacheHandler;
 import org.apache.roller.util.cache.CacheManager;
 import org.apache.roller.util.cache.ExpiringCacheEntry;
 
 
 /**
- * Special cache class for planet content.  We do this as it's own class instead
- * of in a servlet like elsewhere because this cache is shared between the
- * planetrss servlet and the planet.do struts action.
+ * Cache for planet content.
  */
-public class PlanetCache implements CacheHandler {
+public class PlanetCache {
     
     private static Log log = LogFactory.getLog(PlanetCache.class);
     
@@ -55,16 +43,14 @@
     // roller config properties that apply to this cache
     public static final String CACHE_ID = "cache.planet";
     
+    // keep cached content
     private Cache contentCache = null;
     
+    // keep a cached version of last expired time
     private ExpiringCacheEntry lastUpdateTime = null;
     private long timeout = 15 * 60 * 1000;
     
-    // for metrics
-    private double hits = 0;
-    private double misses = 0;
-    private Date startTime = new Date();
-    
+    // reference to our singleton instance
     private static PlanetCache singletonInstance = new PlanetCache();
     
     
@@ -86,7 +72,7 @@
         
         log.info("Planet cache = "+cacheProps);
         
-        contentCache = CacheManager.constructCache(this, cacheProps);
+        contentCache = CacheManager.constructCache(null, cacheProps);
         
         // lookup our timeout value
         String timeoutString = RollerConfig.getProperty("cache.planet.timeout");
@@ -109,10 +95,8 @@
         Object entry = contentCache.get(key);
         
         if(entry == null) {
-            this.misses++;
             log.debug("MISS "+key);
         } else {
-            this.hits++;
             log.debug("HIT "+key);
         }
         
@@ -126,7 +110,20 @@
     }
     
     
-    public Date lastModified() {
+    public void remove(String key) {
+        contentCache.remove(key);
+        log.debug("REMOVE "+key);
+    }
+    
+    
+    public void clear() {
+        contentCache.clear();
+        this.lastUpdateTime = null;
+        log.debug("CLEAR");
+    }
+    
+    
+    public Date getLastModified() {
         
         Date lastModified = null;
         
@@ -154,107 +151,52 @@
         
         return lastModified;
     }
-
-    
-    /**
-     * A weblog entry has changed.
-     */
-    public void invalidate(WeblogEntryData entry) {
-        // ignored
-    }
-    
-    
-    /**
-     * A weblog has changed.
-     */
-    public void invalidate(WebsiteData website) {
-        // ignored
-    }
-    
-    
-    /**
-     * A bookmark has changed.
-     */
-    public void invalidate(BookmarkData bookmark) {
-        // ignored
-    }
-    
-    
-    /**
-     * A folder has changed.
-     */
-    public void invalidate(FolderData folder) {
-        // ignored
-    }
     
     
     /**
-     * A comment has changed.
-     */
-    public void invalidate(CommentData comment) {
-        // ignored
-    }
-    
-    
-    /**
-     * A referer has changed.
-     */
-    public void invalidate(RefererData referer) {
-        // ignored
-    }
-    
-    
-    /**
-     * A user profile has changed.
-     */
-    public void invalidate(UserData user) {
-        // ignored
-    }
-    
-    
-    /**
-     * A category has changed.
-     */
-    public void invalidate(WeblogCategoryData category) {
-        // ignored
-    }
-    
-    
-    /**
-     * A weblog template has changed.
-     */
-    public void invalidate(WeblogTemplate template) {
-        // ignored
-    }
-    
-    
-    /**
-     * Clear the entire cache.
-     */
-    public void clear() {
-        log.info("Clearing cache");
-        this.contentCache.clear();
-        this.startTime = new Date();
-        this.hits = 0;
-        this.misses = 0;
-    }
-    
-    
-    public Map getStats() {
-        
-        Map stats = new HashMap();
-        stats.put("cacheType", this.contentCache.getClass().getName());
-        stats.put("startTime", this.startTime);
-        stats.put("hits", new Double(this.hits));
-        stats.put("misses", new Double(this.misses));
-        
-        // calculate efficiency
-        if(misses > 0) {
-            double efficiency = hits / (misses + hits);
-            stats.put("efficiency", new Double(efficiency * 100));
+     * Generate a cache key from a parsed planet request.
+     * This generates a key of the form ...
+     *
+     * <context>/<type>/<language>[/user]
+     *   or
+     * <context>/<type>[/flavor]/<language>[/excerpts]
+     *
+     *
+     * examples ...
+     *
+     * planet/page/en
+     * planet/feed/rss/en/excerpts
+     *
+     */
+    public String generateKey(PlanetRequest planetRequest) {
+        
+        StringBuffer key = new StringBuffer();
+        
+        key.append(this.CACHE_ID).append(":");
+        key.append(planetRequest.getContext());
+        key.append("/");
+        key.append(planetRequest.getType());
+        
+        if(planetRequest.getFlavor() != null) {
+            key.append("/").append(planetRequest.getFlavor());
+        }
+        
+        // add language
+        key.append("/").append(planetRequest.getLanguage());
+        
+        if(planetRequest.getFlavor() != null) {
+            // add excerpts
+            if(planetRequest.isExcerpts()) {
+                key.append("/excerpts");
+            }
+        } else {
+            // add login state
+            if(planetRequest.getAuthenticUser() != null) {
+                key.append("/user=").append(planetRequest.getAuthenticUser());
+            }
         }
         
-        return stats;
+        return key.toString();
     }
     
 }

Added: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/SiteWideCache.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/SiteWideCache.java?rev=423306&view=auto
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/SiteWideCache.java (added)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/SiteWideCache.java Tue Jul 18 17:15:55 2006
@@ -0,0 +1,342 @@
+/*
+ * 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.ui.rendering.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.pojos.BookmarkData;
+import org.apache.roller.pojos.CommentData;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.RefererData;
+import org.apache.roller.pojos.UserData;
+import org.apache.roller.pojos.WeblogCategoryData;
+import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WeblogTemplate;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.util.cache.Cache;
+import org.apache.roller.util.cache.CacheHandler;
+import org.apache.roller.util.cache.CacheManager;
+import org.apache.roller.util.cache.ExpiringCacheEntry;
+
+
+/**
+ * Cache for site-wide weblog content.
+ */
+public class SiteWideCache implements CacheHandler {
+    
+    private static Log log = LogFactory.getLog(SiteWideCache.class);
+    
+    // a unique identifier for this cache, this is used as the prefix for
+    // roller config properties that apply to this cache
+    public static final String CACHE_ID = "cache.sitewide";
+    
+    // keep cached content
+    private Cache contentCache = null;
+    
+    // keep a cached version of last expired time
+    private ExpiringCacheEntry lastUpdateTime = null;
+    private long timeout = 15 * 60 * 1000;
+    
+    // reference to our singleton instance
+    private static SiteWideCache singletonInstance = new SiteWideCache();
+    
+    
+    private SiteWideCache() {
+        
+        Map cacheProps = new HashMap();
+        cacheProps.put("id", CACHE_ID);
+        Enumeration allProps = RollerConfig.keys();
+        String prop = null;
+        while(allProps.hasMoreElements()) {
+            prop = (String) allProps.nextElement();
+            
+            // we are only interested in props for this cache
+            if(prop.startsWith(CACHE_ID+".")) {
+                cacheProps.put(prop.substring(CACHE_ID.length()+1), 
+                        RollerConfig.getProperty(prop));
+            }
+        }
+        
+        log.info(cacheProps);
+        
+        contentCache = CacheManager.constructCache(this, cacheProps);
+    }
+    
+    
+    public static SiteWideCache getInstance() {
+        return singletonInstance;
+    }
+    
+    
+    public Object get(String key) {
+        
+        Object entry = contentCache.get(key);
+        
+        if(entry == null) {
+            log.debug("MISS "+key);
+        } else {
+            log.debug("HIT "+key);
+        }
+        
+        return entry;
+    }
+    
+    
+    public void put(String key, Object value) {
+        contentCache.put(key, value);
+        log.debug("PUT "+key);
+    }
+
+    
+    public void remove(String key) {
+        contentCache.remove(key);
+        log.debug("REMOVE "+key);
+    }
+    
+    
+    public void clear() {
+        contentCache.clear();
+        this.lastUpdateTime = null;
+        log.debug("CLEAR");
+    }
+    
+    
+    public Date getLastModified() {
+        
+        Date lastModified = null;
+        
+        // first try our cached version
+        if(this.lastUpdateTime != null) {
+            lastModified = (Date) this.lastUpdateTime.getValue();
+        }
+        
+        // still null, we need to get a fresh value
+        if(lastModified == null) {
+            lastModified = new Date();
+            this.lastUpdateTime = new ExpiringCacheEntry(lastModified, this.timeout);
+        }
+        
+        return lastModified;
+    }
+    
+    
+    /**
+     * Generate a cache key from a parsed weblog page request.
+     * This generates a key of the form ...
+     *
+     * <handle>[/anchor][/language][/user]
+     *   or
+     * <handle>[/weblogPage][/date][/category][/language][/user]
+     *
+     *
+     * examples ...
+     *
+     * foo/en
+     * foo/entry_anchor
+     * foo/20051110/en
+     * foo/MyCategory/en/user=myname
+     *
+     */
+    public String generateKey(WeblogPageRequest pageRequest) {
+        
+        StringBuffer key = new StringBuffer();
+        
+        key.append(this.CACHE_ID).append(":");
+        key.append("page/");
+        key.append(pageRequest.getWeblogHandle());
+        
+        if(pageRequest.getWeblogAnchor() != null) {
+            String anchor = null;
+            try {
+                // may contain spaces or other bad chars
+                anchor = URLEncoder.encode(pageRequest.getWeblogAnchor(), "UTF-8");
+            } catch(UnsupportedEncodingException ex) {
+                // ignored
+            }
+            
+            key.append("/").append(anchor);
+        } else {
+            
+            if(pageRequest.getWeblogPageName() != null) {
+                key.append("/").append(pageRequest.getWeblogPageName());
+            }
+            
+            if(pageRequest.getWeblogDate() != null) {
+                key.append("/").append(pageRequest.getWeblogDate());
+            }
+            
+            if(pageRequest.getWeblogCategoryName() != null) {
+                String cat = null;
+                try {
+                    // may contain spaces or other bad chars
+                    cat = URLEncoder.encode(pageRequest.getWeblogCategoryName(), "UTF-8");
+                } catch(UnsupportedEncodingException ex) {
+                    // ignored
+                }
+                
+                key.append("/").append(cat);
+            }
+        }
+        
+        if(pageRequest.getLocale() != null) {
+            key.append("/").append(pageRequest.getLocale());
+        }
+        
+        // add page number when applicable
+        if(pageRequest.getWeblogAnchor() == null) {
+            key.append("/page=").append(pageRequest.getPageNum());
+        }
+        
+        // add login state
+        if(pageRequest.getAuthenticUser() != null) {
+            key.append("/user=").append(pageRequest.getAuthenticUser());
+        }
+        
+        return key.toString();
+    }
+    
+    
+    /**
+     * Generate a cache key from a parsed weblog feed request.
+     * This generates a key of the form ...
+     *
+     * <handle>/<type>/<format>/[/category][/language][/excerpts]
+     *
+     * examples ...
+     *
+     * foo/entries/rss/en
+     * foo/comments/rss/MyCategory/en
+     * foo/entries/atom/en/excerpts
+     *
+     */
+    public String generateKey(WeblogFeedRequest feedRequest) {
+        
+        StringBuffer key = new StringBuffer();
+        
+        key.append(this.CACHE_ID).append(":");
+        key.append("feed/");
+        key.append(feedRequest.getWeblogHandle());
+        
+        key.append("/").append(feedRequest.getType());
+        key.append("/").append(feedRequest.getFormat());
+        
+        if(feedRequest.getWeblogCategoryName() != null) {
+            String cat = feedRequest.getWeblogCategoryName();
+            try {
+                cat = URLEncoder.encode(cat, "UTF-8");
+            } catch (UnsupportedEncodingException ex) {
+                // should never happen, utf-8 is always supported
+            }
+            
+            key.append("/").append(cat);
+        }
+        
+        if(feedRequest.getLocale() != null) {
+            key.append("/").append(feedRequest.getLocale());
+        }
+        
+        if(feedRequest.isExcerpts()) {
+            key.append("/excerpts");
+        }
+        
+        return key.toString();
+    }
+    
+    
+    /**
+     * A weblog entry has changed.
+     */
+    public void invalidate(WeblogEntryData entry) {
+        this.contentCache.clear();
+        this.lastUpdateTime = null;
+    }
+    
+    
+    /**
+     * A weblog has changed.
+     */
+    public void invalidate(WebsiteData website) {
+        this.contentCache.clear();
+        this.lastUpdateTime = null;
+    }
+    
+    
+    /**
+     * A bookmark has changed.
+     */
+    public void invalidate(BookmarkData bookmark) {
+        // ignored
+    }
+    
+    
+    /**
+     * A folder has changed.
+     */
+    public void invalidate(FolderData folder) {
+        // ignored
+    }
+    
+    
+    /**
+     * A comment has changed.
+     */
+    public void invalidate(CommentData comment) {
+        // ignored
+    }
+    
+    
+    /**
+     * A referer has changed.
+     */
+    public void invalidate(RefererData referer) {
+        // ignored
+    }
+    
+    
+    /**
+     * A user profile has changed.
+     */
+    public void invalidate(UserData user) {
+        // ignored
+    }
+    
+    
+    /**
+     * A category has changed.
+     */
+    public void invalidate(WeblogCategoryData category) {
+        // ignored
+    }
+    
+    
+    /**
+     * A weblog template has changed.
+     */
+    public void invalidate(WeblogTemplate template) {
+        // ignored
+    }
+    
+}

Added: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogFeedCache.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogFeedCache.java?rev=423306&view=auto
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogFeedCache.java (added)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogFeedCache.java Tue Jul 18 17:15:55 2006
@@ -0,0 +1,166 @@
+/*
+ * 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.ui.rendering.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.util.Utilities;
+import org.apache.roller.util.cache.Cache;
+import org.apache.roller.util.cache.CacheManager;
+import org.apache.roller.util.cache.LazyExpiringCacheEntry;
+
+
+/**
+ * Cache for weblog feed content.
+ */
+public class WeblogFeedCache {
+    
+    private static Log log = LogFactory.getLog(WeblogFeedCache.class);
+    
+    // a unique identifier for this cache, this is used as the prefix for
+    // roller config properties that apply to this cache
+    public static final String CACHE_ID = "cache.weblogfeed";
+    
+    // keep cached content
+    private Cache contentCache = null;
+    
+    // reference to our singleton instance
+    private static WeblogFeedCache singletonInstance = new WeblogFeedCache();
+    
+    
+    private WeblogFeedCache() {
+        
+        Map cacheProps = new HashMap();
+        cacheProps.put("id", CACHE_ID);
+        Enumeration allProps = RollerConfig.keys();
+        String prop = null;
+        while(allProps.hasMoreElements()) {
+            prop = (String) allProps.nextElement();
+            
+            // we are only interested in props for this cache
+            if(prop.startsWith(CACHE_ID+".")) {
+                cacheProps.put(prop.substring(CACHE_ID.length()+1), 
+                        RollerConfig.getProperty(prop));
+            }
+        }
+        
+        log.info(cacheProps);
+        
+        contentCache = CacheManager.constructCache(null, cacheProps);
+    }
+    
+    
+    public static WeblogFeedCache getInstance() {
+        return singletonInstance;
+    }
+    
+    
+    public Object get(String key, long lastModified) {
+        
+        Object entry = null;
+        
+        LazyExpiringCacheEntry lazyEntry =
+                (LazyExpiringCacheEntry) this.contentCache.get(key);
+        if(lazyEntry != null) {
+            entry = lazyEntry.getValue(lastModified);
+            
+            if(entry != null) {
+                log.debug("HIT "+key);
+            } else {
+                log.debug("HIT-EXPIRED "+key);
+            }
+            
+        } else {
+            log.debug("MISS "+key);
+        }
+        
+        return entry;
+    }
+    
+    
+    public void put(String key, Object value) {
+        contentCache.put(key, new LazyExpiringCacheEntry(value));
+        log.debug("PUT "+key);
+    }
+    
+    
+    public void remove(String key) {
+        contentCache.remove(key);
+        log.debug("REMOVE "+key);
+    }
+    
+    
+    public void clear() {
+        contentCache.clear();
+        log.debug("CLEAR");
+    }
+    
+    
+    /**
+     * Generate a cache key from a parsed weblog feed request.
+     * This generates a key of the form ...
+     *
+     * <handle>/<type>/<format>/[/category][/language][/excerpts]
+     *
+     * examples ...
+     *
+     * foo/entries/rss/en
+     * foo/comments/rss/MyCategory/en
+     * foo/entries/atom/en/excerpts
+     *
+     */
+    public String generateKey(WeblogFeedRequest feedRequest) {
+        
+        StringBuffer key = new StringBuffer();
+        
+        key.append(this.CACHE_ID).append(":");
+        key.append(feedRequest.getWeblogHandle());
+        
+        key.append("/").append(feedRequest.getType());
+        key.append("/").append(feedRequest.getFormat());
+        
+        if(feedRequest.getWeblogCategoryName() != null) {
+            String cat = feedRequest.getWeblogCategoryName();
+            try {
+                cat = URLEncoder.encode(cat, "UTF-8");
+            } catch (UnsupportedEncodingException ex) {
+                // should never happen, utf-8 is always supported
+            }
+            
+            key.append("/").append(cat);
+        }
+        
+        if(feedRequest.getLocale() != null) {
+            key.append("/").append(feedRequest.getLocale());
+        }
+        
+        if(feedRequest.isExcerpts()) {
+            key.append("/excerpts");
+        }
+        
+        return key.toString();
+    }
+    
+}

Added: incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogPageCache.java
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogPageCache.java?rev=423306&view=auto
==============================================================================
--- incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogPageCache.java (added)
+++ incubator/roller/branches/roller_3.0/src/org/apache/roller/ui/rendering/util/WeblogPageCache.java Tue Jul 18 17:15:55 2006
@@ -0,0 +1,195 @@
+/*
+ * 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.ui.rendering.util;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.util.Utilities;
+import org.apache.roller.util.cache.Cache;
+import org.apache.roller.util.cache.CacheManager;
+import org.apache.roller.util.cache.LazyExpiringCacheEntry;
+
+
+/**
+ * Cache for weblog page content.
+ */
+public class WeblogPageCache {
+    
+    private static Log log = LogFactory.getLog(WeblogPageCache.class);
+    
+    // a unique identifier for this cache, this is used as the prefix for
+    // roller config properties that apply to this cache
+    public static final String CACHE_ID = "cache.weblogpage";
+    
+    // keep cached content
+    private Cache contentCache = null;
+    
+    // reference to our singleton instance
+    private static WeblogPageCache singletonInstance = new WeblogPageCache();
+    
+    
+    private WeblogPageCache() {
+        
+        Map cacheProps = new HashMap();
+        cacheProps.put("id", CACHE_ID);
+        Enumeration allProps = RollerConfig.keys();
+        String prop = null;
+        while(allProps.hasMoreElements()) {
+            prop = (String) allProps.nextElement();
+            
+            // we are only interested in props for this cache
+            if(prop.startsWith(CACHE_ID+".")) {
+                cacheProps.put(prop.substring(CACHE_ID.length()+1), 
+                        RollerConfig.getProperty(prop));
+            }
+        }
+        
+        log.info(cacheProps);
+        
+        contentCache = CacheManager.constructCache(null, cacheProps);
+    }
+    
+    
+    public static WeblogPageCache getInstance() {
+        return singletonInstance;
+    }
+    
+    
+    public Object get(String key, long lastModified) {
+        
+        Object entry = null;
+        
+        LazyExpiringCacheEntry lazyEntry =
+                (LazyExpiringCacheEntry) this.contentCache.get(key);
+        if(lazyEntry != null) {
+            entry = lazyEntry.getValue(lastModified);
+            
+            if(entry != null) {
+                log.debug("HIT "+key);
+            } else {
+                log.debug("HIT-EXPIRED "+key);
+            }
+            
+        } else {
+            log.debug("MISS "+key);
+        }
+        
+        return entry;
+    }
+    
+    
+    public void put(String key, Object value) {
+        contentCache.put(key, new LazyExpiringCacheEntry(value));
+        log.debug("PUT "+key);
+    }
+    
+    
+    public void remove(String key) {
+        contentCache.remove(key);
+        log.debug("REMOVE "+key);
+    }
+    
+    
+    public void clear() {
+        contentCache.clear();
+        log.debug("CLEAR");
+    }
+    
+    
+    /**
+     * Generate a cache key from a parsed weblog page request.
+     * This generates a key of the form ...
+     *
+     * <handle>[/anchor][/language][/user]
+     *   or
+     * <handle>[/weblogPage][/date][/category][/language][/user]
+     *
+     *
+     * examples ...
+     *
+     * foo/en
+     * foo/entry_anchor
+     * foo/20051110/en
+     * foo/MyCategory/en/user=myname
+     *
+     */
+    public String generateKey(WeblogPageRequest pageRequest) {
+        
+        StringBuffer key = new StringBuffer();
+        
+        key.append(this.CACHE_ID).append(":");
+        key.append(pageRequest.getWeblogHandle());
+        
+        if(pageRequest.getWeblogAnchor() != null) {
+            String anchor = null;
+            try {
+                // may contain spaces or other bad chars
+                anchor = URLEncoder.encode(pageRequest.getWeblogAnchor(), "UTF-8");
+            } catch(UnsupportedEncodingException ex) {
+                // ignored
+            }
+            
+            key.append("/").append(anchor);
+        } else {
+            
+            if(pageRequest.getWeblogPageName() != null) {
+                key.append("/").append(pageRequest.getWeblogPageName());
+            }
+            
+            if(pageRequest.getWeblogDate() != null) {
+                key.append("/").append(pageRequest.getWeblogDate());
+            }
+            
+            if(pageRequest.getWeblogCategoryName() != null) {
+                String cat = null;
+                try {
+                    // may contain spaces or other bad chars
+                    cat = URLEncoder.encode(pageRequest.getWeblogCategoryName(), "UTF-8");
+                } catch(UnsupportedEncodingException ex) {
+                    // ignored
+                }
+                
+                key.append("/").append(cat);
+            }
+        }
+        
+        if(pageRequest.getLocale() != null) {
+            key.append("/").append(pageRequest.getLocale());
+        }
+        
+        // add page number when applicable
+        if(pageRequest.getWeblogAnchor() == null) {
+            key.append("/page=").append(pageRequest.getPageNum());
+        }
+        
+        // add login state
+        if(pageRequest.getAuthenticUser() != null) {
+            key.append("/user=").append(pageRequest.getAuthenticUser());
+        }
+        
+        return key.toString();
+    }
+    
+}

Modified: incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties
URL: http://svn.apache.org/viewvc/incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties?rev=423306&r1=423305&r2=423306&view=diff
==============================================================================
--- incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties (original)
+++ incubator/roller/branches/roller_3.0/web/WEB-INF/classes/roller.properties Tue Jul 18 17:15:55 2006
@@ -130,32 +130,29 @@
 cache.defaultFactory=org.apache.roller.util.cache.ExpiringLRUCacheFactoryImpl
 cache.customHandlers=
 
+# set "true" to NOT cache the custom pages for users who are logged in
+cache.excludeOwnerEditPages=false
+
 # This sets how many minutes into the future we look to prepare
 # entries posted into the future which need to be invalidated from the cache.
 # It is very unlikely that this should ever need to be changed
 cache.futureInvalidations.peerTime=3
 
-# Main page cache (this is low on purpose)
-cache.mainpage.size=10
-cache.mainpage.timeout=1800
-# set "true" to NOT cache the custom pages for users who are logged in
-cache.mainpage.excludeOwnerEditPages=false
+# Site-wide cache (all content for site-wide frontpage weblog)
+cache.sitewide.size=50
+cache.sitewide.timeout=1800
 
 # Weblog page cache (all the weblog content)
 cache.weblogpage.size=400
 cache.weblogpage.timeout=3600
-# set "true" to NOT cache the custom pages for users who are logged in
-cache.weblogpage.excludeOwnerEditPages=false
 
 # Feed cache (xml feeds like rss, atom, etc)
-cache.feed.size=200
-cache.feed.timeout=3600
+cache.weblogfeed.size=200
+cache.weblogfeed.timeout=3600
 
 # Planet cache (planet page and rss feed)
 cache.planet.size=10
 cache.planet.timeout=1800
-# set "true" to NOT cache the custom pages for users who are logged in
-cache.planet.excludeOwnerEditPages=false
 
 #----------------------------------
 # Secure login configs



Mime
View raw message