File Source: PlanetCache.java

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   *  contributor license agreements.  The ASF licenses this file to You
     4   * under the Apache License, Version 2.0 (the "License"); you may not
     5   * use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.  For additional information regarding
    15   * copyright in this work, please see the NOTICE file in the top level
    16   * directory of this distribution.
    17   */
    18  
    19  package org.apache.roller.weblogger.ui.rendering.util.cache;
    20  
    21  import java.util.Date;
    22  import java.util.Enumeration;
    23  import java.util.HashMap;
    24  import java.util.Map;
    25  import org.apache.commons.logging.Log;
    26  import org.apache.commons.logging.LogFactory;
    27  import org.apache.roller.weblogger.WebloggerException;
    28  import org.apache.roller.weblogger.config.WebloggerConfig;
    29  import org.apache.roller.weblogger.business.WebloggerFactory;
    30  import org.apache.roller.planet.business.Planet;
    31  import org.apache.roller.planet.business.PlanetFactory;
    32  import org.apache.roller.planet.business.PlanetManager;
    33  import org.apache.roller.weblogger.ui.rendering.util.PlanetRequest;
    34  import org.apache.roller.weblogger.util.cache.Cache;
    35  import org.apache.roller.weblogger.util.cache.CacheManager;
    36  import org.apache.roller.weblogger.util.cache.ExpiringCacheEntry;
    37  
    38  
    39  /**
    40   * Cache for planet content.
    41   */
    42  public class PlanetCache {
    43      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.ui.rendering.util.cache.PlanetCache__static_init
              * 
              *  Presumptions:
              *    org.apache.commons.logging.LogFactory:getLog(...)@44 != null
              * 
              *  Postconditions:
              *    (soft) log != null
              *    singletonInstance == &new PlanetCache(PlanetCache__static_init#1)
              *    new PlanetCache(PlanetCache__static_init#1) num objects == 1
              *    init'ed(singletonInstance.cacheEnabled)
              *    init'ed(singletonInstance.contentCache)
              *    singletonInstance.lastUpdateTime == null
              *    singletonInstance.timeout in -9_223_372_036_854_775_000..18_446_744_073_709_551_000
              */
    44      private static Log log = LogFactory.getLog(PlanetCache.class);
    45      
    46      // a unique identifier for this cache, this is used as the prefix for
    47      // roller config properties that apply to this cache
    48      public static final String CACHE_ID = "cache.planet";
    49      
    50      // keep cached content
    51      private boolean cacheEnabled = true;
    52      private Cache contentCache = null;
    53      
    54      // keep a cached version of last expired time
    55      private ExpiringCacheEntry lastUpdateTime = null;
    56      private long timeout = 15 * 60 * 1000;
    57      
    58      // reference to our singleton instance
    59      private static PlanetCache singletonInstance = new PlanetCache();
    60      
    61      
             /* 
    P/P       *  Method: void org.apache.roller.weblogger.ui.rendering.util.cache.PlanetCache()
              * 
              *  Preconditions:
              *    log != null
              * 
              *  Presumptions:
              *    java.lang.Long:parseLong(...)@91 in -9_223_372_036_854_775..18_446_744_073_709_551
              *    java.lang.String:length(...)@75 <= 232-2
              *    java.util.Enumeration:nextElement(...)@71 != null
              *    org.apache.roller.weblogger.config.WebloggerConfig:keys(...)@68 != null
              * 
              *  Postconditions:
              *    init'ed(this.cacheEnabled)
              *    init'ed(this.contentCache)
              *    this.lastUpdateTime == null
              *    this.timeout in -9_223_372_036_854_775_000..18_446_744_073_709_551_000
              * 
              *  Test Vectors:
              *    java.lang.String:startsWith(...)@74: {0}, {1}
              *    java.util.Enumeration:hasMoreElements(...)@70: {0}, {1}
              *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@64: {0}, {1}
              */
    62      private PlanetCache() {
    63          
    64          cacheEnabled = WebloggerConfig.getBooleanProperty(CACHE_ID+".enabled");
    65          
    66          Map cacheProps = new HashMap();
    67          cacheProps.put("id", CACHE_ID);
    68          Enumeration allProps = WebloggerConfig.keys();
    69          String prop = null;
    70          while(allProps.hasMoreElements()) {
    71              prop = (String) allProps.nextElement();
    72              
    73              // we are only interested in props for this cache
    74              if(prop.startsWith(CACHE_ID+".")) {
    75                  cacheProps.put(prop.substring(CACHE_ID.length()+1), 
    76                          WebloggerConfig.getProperty(prop));
    77              }
    78          }
    79          
    80          log.info("Planet cache = "+cacheProps);
    81          
    82          if(cacheEnabled) {
    83              contentCache = CacheManager.constructCache(null, cacheProps);
    84          } else {
    85              log.warn("Caching has been DISABLED");
    86          }
    87          
    88          // lookup our timeout value
    89          String timeoutString = WebloggerConfig.getProperty("cache.planet.timeout");
    90          try {
    91              long timeoutSecs = Long.parseLong(timeoutString);
    92              this.timeout = timeoutSecs * 1000;
    93          } catch(Exception e) {
    94              // ignored ... illegal value
    95          }
    96      }
    97      
    98      
    99      public static PlanetCache getInstance() {
                 /* 
    P/P           *  Method: PlanetCache getInstance()
                  * 
                  *  Preconditions:
                  *    init'ed(singletonInstance)
                  * 
                  *  Postconditions:
                  *    return_value == singletonInstance
                  *    init'ed(return_value)
                  */
   100          return singletonInstance;
   101      }
   102      
   103      
   104      public Object get(String key) {
   105          
                 /* 
    P/P           *  Method: Object get(String)
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) log != null
                  *    (soft) this.contentCache != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  *    org.apache.roller.weblogger.util.cache.Cache:get(...)@109: Inverse{null}, Addr_Set{null}
                  */
   106          if(!cacheEnabled)
   107              return null;
   108          
   109          Object entry = contentCache.get(key);
   110          
   111          if(entry == null) {
   112              log.debug("MISS "+key);
   113          } else {
   114              log.debug("HIT "+key);
   115          }
   116          
   117          return entry;
   118      }
   119      
   120      
   121      public void put(String key, Object value) {
   122          
                 /* 
    P/P           *  Method: void put(String, Object)
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) log != null
                  *    (soft) this.contentCache != null
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  */
   123          if(!cacheEnabled)
   124              return;
   125          
   126          contentCache.put(key, value);
   127          log.debug("PUT "+key);
   128      }
   129      
   130      
   131      public void remove(String key) {
   132          
                 /* 
    P/P           *  Method: void remove(String)
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) log != null
                  *    (soft) this.contentCache != null
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  */
   133          if(!cacheEnabled)
   134              return;
   135          
   136          contentCache.remove(key);
   137          log.debug("REMOVE "+key);
   138      }
   139      
   140      
   141      public void clear() {
   142          
                 /* 
    P/P           *  Method: void clear()
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) log != null
                  *    (soft) this.contentCache != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  */
   143          if(!cacheEnabled)
   144              return;
   145          
   146          contentCache.clear();
   147          this.lastUpdateTime = null;
   148          log.debug("CLEAR");
   149      }
   150      
   151      
   152      public Date getLastModified() {
   153          
                 /* 
    P/P           *  Method: Date getLastModified()
                  * 
                  *  Preconditions:
                  *    init'ed(this.lastUpdateTime)
                  *    (soft) log != null
                  *    (soft) init'ed(this.timeout)
                  * 
                  *  Postconditions:
                  *    return_value != null
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, &new ExpiringCacheEntry(getLastModified#2)}
                  *    this.lastUpdateTime != null
                  *    new Date(getLastModified#1) num objects <= 1
                  *    new ExpiringCacheEntry(getLastModified#2) num objects <= 1
                  * 
                  *  Test Vectors:
                  *    this.lastUpdateTime: Addr_Set{null}, Inverse{null}
                  */
   154          Date lastModified = null;
   155          
   156          // first try our cached version
   157          if(this.lastUpdateTime != null) {
   158              lastModified = (Date) this.lastUpdateTime.getValue();
   159          }
   160          
   161          // still null, we need to get a fresh value
   162          if(lastModified == null) {
   163              
   164              // TODO: ROLLER40 last updated for planet
   165              lastModified = null; // PlanetFactory.getPlanet().getPlanetManager().getLastUpdated();
   166              
+  167              if (lastModified == null) {
   168                  lastModified = new Date();
   169                  log.warn("Can't get lastUpdate time, using current time instead");
   170              }
   171              
   172              this.lastUpdateTime = new ExpiringCacheEntry(lastModified, this.timeout);
   173          }
   174          
   175          return lastModified;
   176      }
   177      
   178      
   179      /**
   180       * Generate a cache key from a parsed planet request.
   181       * This generates a key of the form ...
   182       *
   183       * <context>/<type>/<language>[/user]
   184       *   or
   185       * <context>/<type>[/flavor]/<language>[/excerpts]
   186       *
   187       *
   188       * examples ...
   189       *
   190       * planet/page/en
   191       * planet/feed/rss/en/excerpts
   192       *
   193       */
   194      public String generateKey(PlanetRequest planetRequest) {
   195          
                 /* 
    P/P           *  Method: String generateKey(PlanetRequest)
                  * 
                  *  Preconditions:
                  *    planetRequest != null
                  *    init'ed(planetRequest.context)
                  *    init'ed(planetRequest.flavor)
                  *    init'ed(planetRequest.group)
                  *    init'ed(planetRequest.language)
                  *    init'ed(planetRequest.type)
                  *    (soft) init'ed(planetRequest.authenticUser)
                  *    (soft) init'ed(planetRequest.excerpts)
                  * 
                  *  Postconditions:
                  *    init'ed(java.lang.StringBuffer:toString(...)._tainted)
                  *    return_value == &java.lang.StringBuffer:toString(...)
                  * 
                  *  Test Vectors:
                  *    planetRequest.authenticUser: Addr_Set{null}, Inverse{null}
                  *    planetRequest.excerpts: {0}, {1}
                  *    planetRequest.flavor: Addr_Set{null}, Inverse{null}
                  *    planetRequest.group: Addr_Set{null}, Inverse{null}
                  */
   196          StringBuffer key = new StringBuffer();
   197          
   198          key.append(this.CACHE_ID).append(":");
   199          key.append(planetRequest.getContext());
   200          key.append("/");
   201          key.append(planetRequest.getType());
   202          
   203          if(planetRequest.getFlavor() != null) {
   204              key.append("/").append(planetRequest.getFlavor());
   205          }
   206          
   207          // add language
   208          key.append("/").append(planetRequest.getLanguage());
   209          
   210          if(planetRequest.getFlavor() != null) {
   211              // add excerpts
   212              if(planetRequest.isExcerpts()) {
   213                  key.append("/excerpts");
   214              }
   215          } else {
   216              // add login state
   217              if(planetRequest.getAuthenticUser() != null) {
   218                  key.append("/user=").append(planetRequest.getAuthenticUser());
   219              }
   220          }
   221          
   222          // add group
   223          if (planetRequest.getGroup() != null) {
   224              key.append("/group=").append(planetRequest.getGroup());
   225          }
   226  
   227          return key.toString();
   228      }
   229      
   230  }








SofCheck Inspector Build Version : 2.18479
PlanetCache.java 2009-Jan-02 14:25:06
PlanetCache.class 2009-Sep-04 03:12:45