File Source: SiteWideCache.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.io.UnsupportedEncodingException;
    22  import java.net.URLEncoder;
    23  import java.util.Date;
    24  import java.util.Enumeration;
    25  import java.util.HashMap;
    26  import java.util.Iterator;
    27  import java.util.Map;
    28  import java.util.Set;
    29  import java.util.TreeSet;
    30  import org.apache.commons.logging.Log;
    31  import org.apache.commons.logging.LogFactory;
    32  import org.apache.roller.weblogger.config.WebloggerConfig;
    33  import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
    34  import org.apache.roller.weblogger.pojos.WeblogBookmark;
    35  import org.apache.roller.weblogger.pojos.WeblogEntryComment;
    36  import org.apache.roller.weblogger.pojos.WeblogBookmarkFolder;
    37  import org.apache.roller.weblogger.pojos.WeblogReferrer;
    38  import org.apache.roller.weblogger.pojos.User;
    39  import org.apache.roller.weblogger.pojos.WeblogCategory;
    40  import org.apache.roller.weblogger.pojos.WeblogEntry;
    41  import org.apache.roller.weblogger.pojos.WeblogTemplate;
    42  import org.apache.roller.weblogger.pojos.Weblog;
    43  import org.apache.roller.weblogger.ui.rendering.util.WeblogFeedRequest;
    44  import org.apache.roller.weblogger.ui.rendering.util.WeblogPageRequest;
    45  import org.apache.roller.weblogger.util.Utilities;
    46  import org.apache.roller.weblogger.util.cache.Cache;
    47  import org.apache.roller.weblogger.util.cache.CacheHandler;
    48  import org.apache.roller.weblogger.util.cache.CacheManager;
    49  import org.apache.roller.weblogger.util.cache.ExpiringCacheEntry;
    50  
    51  
    52  /**
    53   * Cache for site-wide weblog content.
    54   */
    55  public class SiteWideCache implements CacheHandler {
    56      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.ui.rendering.util.cache.SiteWideCache__static_init
              * 
              *  Presumptions:
              *    org.apache.commons.logging.LogFactory:getLog(...)@57 != null
              * 
              *  Postconditions:
              *    (soft) log != null
              *    singletonInstance == &new SiteWideCache(SiteWideCache__static_init#1)
              *    new SiteWideCache(SiteWideCache__static_init#1) num objects == 1
              *    init'ed(singletonInstance.cacheEnabled)
              *    init'ed(singletonInstance.contentCache)
              *    singletonInstance.lastUpdateTime == null
              *    singletonInstance.timeout == 900_000
              */
    57      private static Log log = LogFactory.getLog(SiteWideCache.class);
    58      
    59      // a unique identifier for this cache, this is used as the prefix for
    60      // roller config properties that apply to this cache
    61      public static final String CACHE_ID = "cache.sitewide";
    62      
    63      // keep cached content
    64      private boolean cacheEnabled = true;
    65      private Cache contentCache = null;
    66      
    67      // keep a cached version of last expired time
    68      private ExpiringCacheEntry lastUpdateTime = null;
    69      private long timeout = 15 * 60 * 1000;
    70      
    71      // reference to our singleton instance
    72      private static SiteWideCache singletonInstance = new SiteWideCache();
    73      
    74      
             /* 
    P/P       *  Method: void org.apache.roller.weblogger.ui.rendering.util.cache.SiteWideCache()
              * 
              *  Preconditions:
              *    log != null
              * 
              *  Presumptions:
              *    java.lang.String:length(...)@88 <= 232-2
              *    java.util.Enumeration:nextElement(...)@84 != null
              *    org.apache.roller.weblogger.config.WebloggerConfig:keys(...)@81 != null
              * 
              *  Postconditions:
              *    init'ed(this.cacheEnabled)
              *    init'ed(this.contentCache)
              *    this.lastUpdateTime == null
              *    this.timeout == 900_000
              * 
              *  Test Vectors:
              *    java.lang.String:startsWith(...)@87: {0}, {1}
              *    java.util.Enumeration:hasMoreElements(...)@83: {0}, {1}
              *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@77: {0}, {1}
              */
    75      private SiteWideCache() {
    76          
    77          cacheEnabled = WebloggerConfig.getBooleanProperty(CACHE_ID+".enabled");
    78          
    79          Map cacheProps = new HashMap();
    80          cacheProps.put("id", CACHE_ID);
    81          Enumeration allProps = WebloggerConfig.keys();
    82          String prop = null;
    83          while(allProps.hasMoreElements()) {
    84              prop = (String) allProps.nextElement();
    85              
    86              // we are only interested in props for this cache
    87              if(prop.startsWith(CACHE_ID+".")) {
    88                  cacheProps.put(prop.substring(CACHE_ID.length()+1), 
    89                          WebloggerConfig.getProperty(prop));
    90              }
    91          }
    92          
    93          log.info(cacheProps);
    94          
    95          if(cacheEnabled) {
    96              contentCache = CacheManager.constructCache(this, cacheProps);
    97          } else {
    98              log.warn("Caching has been DISABLED");
    99          }
   100      }
   101      
   102      
   103      public static SiteWideCache getInstance() {
                 /* 
    P/P           *  Method: SiteWideCache getInstance()
                  * 
                  *  Preconditions:
                  *    init'ed(singletonInstance)
                  * 
                  *  Postconditions:
                  *    return_value == singletonInstance
                  *    init'ed(return_value)
                  */
   104          return singletonInstance;
   105      }
   106      
   107      
   108      public Object get(String key) {
   109          
                 /* 
    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(...)@113: Inverse{null}, Addr_Set{null}
                  */
   110          if(!cacheEnabled)
   111              return null;
   112          
   113          Object entry = contentCache.get(key);
   114          
   115          if(entry == null) {
   116              log.debug("MISS "+key);
   117          } else {
   118              log.debug("HIT "+key);
   119          }
   120          
   121          return entry;
   122      }
   123      
   124      
   125      public void put(String key, Object value) {
   126          
                 /* 
    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}
                  */
   127          if(!cacheEnabled)
   128              return;
   129          
   130          contentCache.put(key, value);
   131          log.debug("PUT "+key);
   132      }
   133  
   134      
   135      public void remove(String key) {
   136          
                 /* 
    P/P           *  Method: void remove(String)
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) log != null
                  *    (soft) this.contentCache != null
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  */
   137          if(!cacheEnabled)
   138              return;
   139          
   140          contentCache.remove(key);
   141          log.debug("REMOVE "+key);
   142      }
   143      
   144      
   145      public void clear() {
   146          
                 /* 
    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}
                  */
   147          if(!cacheEnabled)
   148              return;
   149          
   150          contentCache.clear();
   151          this.lastUpdateTime = null;
   152          log.debug("CLEAR");
   153      }
   154      
   155      
   156      public Date getLastModified() {
   157          
                 /* 
    P/P           *  Method: Date getLastModified()
                  * 
                  *  Preconditions:
                  *    init'ed(this.lastUpdateTime)
                  *    (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}
                  */
   158          Date lastModified = null;
   159          
   160          // first try our cached version
   161          if(this.lastUpdateTime != null) {
   162              lastModified = (Date) this.lastUpdateTime.getValue();
   163          }
   164          
   165          // still null, we need to get a fresh value
   166          if(lastModified == null) {
   167              lastModified = new Date();
   168              this.lastUpdateTime = new ExpiringCacheEntry(lastModified, this.timeout);
   169          }
   170          
   171          return lastModified;
   172      }
   173      
   174      
   175      /**
   176       * Generate a cache key from a parsed weblog page request.
   177       * This generates a key of the form ...
   178       *
   179       * <handle>/<ctx>[/anchor][/language][/user]
   180       *   or
   181       * <handle>/<ctx>[/weblogPage][/date][/category][/tags][/language][/user]
   182       *
   183       *
   184       * examples ...
   185       *
   186       * foo/en
   187       * foo/entry_anchor
   188       * foo/20051110/en
   189       * foo/MyCategory/en/user=myname
   190       *
   191       */
   192      public String generateKey(WeblogPageRequest pageRequest) {
   193          
                 /* 
    P/P           *  Method: String generateKey(WeblogPageRequest)
                  * 
                  *  Preconditions:
                  *    pageRequest != null
                  *    pageRequest.customParams != null
                  *    init'ed(pageRequest.locale)
                  *    init'ed(pageRequest.weblogAnchor)
                  *    init'ed(pageRequest.weblogHandle)
                  *    (soft) init'ed(pageRequest.authenticUser)
                  *    (soft) init'ed(pageRequest.context)
                  *    (soft) init'ed(pageRequest.pageNum)
                  *    (soft) init'ed(pageRequest.tags)
                  *    (soft) init'ed(pageRequest.weblogCategoryName)
                  *    ...
                  * 
                  *  Presumptions:
                  *    java.util.Set:size(...)@236 >= 0
                  * 
                  *  Postconditions:
                  *    init'ed(java.lang.StringBuffer:toString(...)._tainted)
                  *    return_value == &java.lang.StringBuffer:toString(...)
                  * 
                  *  Test Vectors:
                  *    pageRequest.locale: Addr_Set{null}, Inverse{null}
                  *    pageRequest.tags: Addr_Set{null}, Inverse{null}
                  *    pageRequest.weblogAnchor: Addr_Set{null}, Inverse{null}
                  *    pageRequest.weblogCategoryName: Addr_Set{null}, Inverse{null}
                  *    pageRequest.weblogDate: Addr_Set{null}, Inverse{null}
                  *    pageRequest.weblogPageName: Addr_Set{null}, Inverse{null}
                  *    java.lang.String:equals(...)@232: {0}, {1}
                  *    java.util.List:size(...)@234: {-231..0}, {1..232-1}
                  *    java.util.Map:size(...)@257: {-231..0}, {1..232-1}
                  */
   194          StringBuffer key = new StringBuffer();
   195          
   196          key.append(this.CACHE_ID).append(":");
   197          key.append("page/");
   198          key.append(pageRequest.getWeblogHandle());
   199          
   200          if(pageRequest.getWeblogAnchor() != null) {
   201              String anchor = null;
   202              try {
   203                  // may contain spaces or other bad chars
   204                  anchor = URLEncoder.encode(pageRequest.getWeblogAnchor(), "UTF-8");
   205              } catch(UnsupportedEncodingException ex) {
   206                  // ignored
   207              }
   208              
   209              key.append("/entry/").append(anchor);
   210          } else {
   211              
   212              if(pageRequest.getWeblogPageName() != null) {
   213                  key.append("/page/").append(pageRequest.getWeblogPageName());
   214              }
   215              
   216              if(pageRequest.getWeblogDate() != null) {
   217                  key.append("/").append(pageRequest.getWeblogDate());
   218              }
   219              
   220              if(pageRequest.getWeblogCategoryName() != null) {
   221                  String cat = null;
   222                  try {
   223                      // may contain spaces or other bad chars
   224                      cat = URLEncoder.encode(pageRequest.getWeblogCategoryName(), "UTF-8");
   225                  } catch(UnsupportedEncodingException ex) {
   226                      // ignored
   227                  }
   228                  
   229                  key.append("/").append(cat);
   230              }
   231              
   232              if("tags".equals(pageRequest.getContext())) {
   233                  key.append("/tags/");
   234                  if(pageRequest.getTags() != null && pageRequest.getTags().size() > 0) {
   235                      Set ordered = new TreeSet(pageRequest.getTags());
   236                      String[] tags = (String[]) ordered.toArray(new String[ordered.size()]);
   237                      key.append(Utilities.stringArrayToString(tags,"+"));
   238                  }
   239              }
   240          }
   241          
   242          if(pageRequest.getLocale() != null) {
   243              key.append("/").append(pageRequest.getLocale());
   244          }
   245          
   246          // add page number when applicable
   247          if(pageRequest.getWeblogAnchor() == null) {
   248              key.append("/page=").append(pageRequest.getPageNum());
   249          }
   250          
   251          // add login state
   252          if(pageRequest.getAuthenticUser() != null) {
   253              key.append("/user=").append(pageRequest.getAuthenticUser());
   254          }
   255          
   256          // we allow for arbitrary query params for custom pages
   257          if(pageRequest.getCustomParams().size() > 0) {
   258              String queryString = paramsToString(pageRequest.getCustomParams());
   259              
   260              key.append("/qp=").append(queryString);
   261          }
   262  
   263          return key.toString();
   264      }
   265      
   266      
   267      /**
   268       * Generate a cache key from a parsed weblog feed request.
   269       * This generates a key of the form ...
   270       *
   271       * <handle>/<type>/<format>/[/category][/language][/excerpts]
   272       *
   273       * examples ...
   274       *
   275       * foo/entries/rss/en
   276       * foo/comments/rss/MyCategory/en
   277       * foo/entries/atom/en/excerpts
   278       *
   279       */
   280      public String generateKey(WeblogFeedRequest feedRequest) {
   281          
                 /* 
    P/P           *  Method: String generateKey(WeblogFeedRequest)
                  * 
                  *  Preconditions:
                  *    feedRequest != null
                  *    init'ed(feedRequest.excerpts)
                  *    init'ed(feedRequest.format)
                  *    init'ed(feedRequest.locale)
                  *    init'ed(feedRequest.tags)
                  *    init'ed(feedRequest.type)
                  *    init'ed(feedRequest.weblogCategoryName)
                  *    init'ed(feedRequest.weblogHandle)
                  * 
                  *  Presumptions:
                  *    java.util.List:size(...)@311 >= 0
                  * 
                  *  Postconditions:
                  *    init'ed(java.lang.StringBuffer:toString(...)._tainted)
                  *    return_value == &java.lang.StringBuffer:toString(...)
                  * 
                  *  Test Vectors:
                  *    feedRequest.excerpts: {0}, {1}
                  *    feedRequest.locale: Addr_Set{null}, Inverse{null}
                  *    feedRequest.tags: Addr_Set{null}, Inverse{null}
                  *    feedRequest.weblogCategoryName: Addr_Set{null}, Inverse{null}
                  *    java.util.List:size(...)@310: {-231..0}, {1..232-1}
                  */
   282          StringBuffer key = new StringBuffer();
   283          
   284          key.append(this.CACHE_ID).append(":");
   285          key.append("feed/");
   286          key.append(feedRequest.getWeblogHandle());
   287          
   288          key.append("/").append(feedRequest.getType());
   289          key.append("/").append(feedRequest.getFormat());
   290          
   291          if(feedRequest.getWeblogCategoryName() != null) {
   292              String cat = feedRequest.getWeblogCategoryName();
   293              try {
   294                  cat = URLEncoder.encode(cat, "UTF-8");
   295              } catch (UnsupportedEncodingException ex) {
   296                  // should never happen, utf-8 is always supported
   297              }
   298              
   299              key.append("/").append(cat);
   300          }
   301          
   302          if(feedRequest.getLocale() != null) {
   303              key.append("/").append(feedRequest.getLocale());
   304          }
   305          
   306          if(feedRequest.isExcerpts()) {
   307              key.append("/excerpts");
   308          }
   309          
   310          if(feedRequest.getTags() != null && feedRequest.getTags().size() > 0) {
   311            String[] tags = new String[feedRequest.getTags().size()];
   312            new TreeSet(feedRequest.getTags()).toArray(tags);
   313            key.append("/tags/").append(Utilities.stringArrayToString(tags,"+"));
   314          }       
   315          
   316          return key.toString();
   317      }
   318      
   319      
   320      /**
   321       * A weblog entry has changed.
   322       */
   323      public void invalidate(WeblogEntry entry) {
   324          
                 /* 
    P/P           *  Method: void invalidate(WeblogEntry)
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  */
   325          if(!cacheEnabled)
   326              return;
   327          
   328          this.contentCache.clear();
   329          this.lastUpdateTime = null;
   330      }
   331      
   332      
   333      /**
   334       * A weblog has changed.
   335       */
   336      public void invalidate(Weblog website) {
   337          
                 /* 
    P/P           *  Method: void invalidate(Weblog)
                  * 
                  *  Preconditions:
                  *    init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    this.cacheEnabled: {1}, {0}
                  */
   338          if(!cacheEnabled)
   339              return;
   340          
   341          this.contentCache.clear();
   342          this.lastUpdateTime = null;
   343      }
   344      
   345      
   346      /**
   347       * A bookmark has changed.
   348       */
   349      public void invalidate(WeblogBookmark bookmark) {
                 /* 
    P/P           *  Method: void invalidate(WeblogBookmark)
                  * 
                  *  Preconditions:
                  *    bookmark != null
                  *    (soft) init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogBookmark:getWebsite(...)@350 != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:isSiteWideWeblog(...)@350: {0}, {1}
                  */
   350          if(WebloggerRuntimeConfig.isSiteWideWeblog(bookmark.getWebsite().getHandle())) {
   351              invalidate(bookmark.getWebsite());
   352          }
   353      }
   354      
   355      
   356      /**
   357       * A folder has changed.
   358       */
   359      public void invalidate(WeblogBookmarkFolder folder) {
                 /* 
    P/P           *  Method: void invalidate(WeblogBookmarkFolder)
                  * 
                  *  Preconditions:
                  *    folder != null
                  *    (soft) init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogBookmarkFolder:getWebsite(...)@360 != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:isSiteWideWeblog(...)@360: {0}, {1}
                  */
   360          if(WebloggerRuntimeConfig.isSiteWideWeblog(folder.getWebsite().getHandle())) {
   361              invalidate(folder.getWebsite());
   362          }
   363      }
   364      
   365      
   366      /**
   367       * A comment has changed.
   368       */
   369      public void invalidate(WeblogEntryComment comment) {
                 /* 
    P/P           *  Method: void invalidate(WeblogEntryComment)
                  * 
                  *  Preconditions:
                  *    comment != null
                  *    (soft) init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@370 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntryComment:getWeblogEntry(...)@370 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntryComment:getWeblogEntry(...)@371 != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:isSiteWideWeblog(...)@370: {0}, {1}
                  */
   370          if(WebloggerRuntimeConfig.isSiteWideWeblog(comment.getWeblogEntry().getWebsite().getHandle())) {
   371              invalidate(comment.getWeblogEntry().getWebsite());
   372          }
   373      }
   374      
   375      
   376      /**
   377       * A referer has changed.
   378       */
   379      public void invalidate(WeblogReferrer referer) {
   380          // ignored
             /* 
    P/P       *  Method: void invalidate(WeblogReferrer)
              */
   381      }
   382      
   383      
   384      /**
   385       * A user profile has changed.
   386       */
   387      public void invalidate(User user) {
   388          // ignored
             /* 
    P/P       *  Method: void invalidate(User)
              */
   389      }
   390      
   391      
   392      /**
   393       * A category has changed.
   394       */
   395      public void invalidate(WeblogCategory category) {
                 /* 
    P/P           *  Method: void invalidate(WeblogCategory)
                  * 
                  *  Preconditions:
                  *    category != null
                  *    (soft) init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWebsite(...)@396 != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:isSiteWideWeblog(...)@396: {0}, {1}
                  */
   396          if(WebloggerRuntimeConfig.isSiteWideWeblog(category.getWebsite().getHandle())) {
   397              invalidate(category.getWebsite());
   398          }
   399      }
   400      
   401      
   402      /**
   403       * A weblog template has changed.
   404       */
   405      public void invalidate(WeblogTemplate template) {
                 /* 
    P/P           *  Method: void invalidate(WeblogTemplate)
                  * 
                  *  Preconditions:
                  *    template != null
                  *    (soft) init'ed(this.cacheEnabled)
                  *    (soft) this.contentCache != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogTemplate:getWebsite(...)@406 != null
                  * 
                  *  Postconditions:
                  *    this.lastUpdateTime == One-of{old this.lastUpdateTime, null}
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:isSiteWideWeblog(...)@406: {0}, {1}
                  */
   406          if(WebloggerRuntimeConfig.isSiteWideWeblog(template.getWebsite().getHandle())) {
   407              invalidate(template.getWebsite());
   408          }
   409      }
   410      
   411      
   412      private String paramsToString(Map map) {
   413          
                 /* 
    P/P           *  Method: String paramsToString(Map)
                  * 
                  *  Presumptions:
                  *    java.util.Map:keySet(...)@422 != null
                  *    value.length@425 >= 1
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    map: Inverse{null}, Addr_Set{null}
                  *    java.util.Iterator:hasNext(...)@423: {0}, {1}
                  *    java.util.Map:get(...)@425: Addr_Set{null}, Inverse{null}
                  */
   414          if(map == null) {
   415              return null;
   416          }
   417          
   418          StringBuffer string = new StringBuffer();
   419          
   420          String key = null;
   421          String[] value = null;
   422          Iterator keys = map.keySet().iterator();
   423          while(keys.hasNext()) {
   424              key = (String) keys.next();
   425              value = (String[]) map.get(key);
   426              
   427              if(value != null) {
   428                  string.append(",").append(key).append("=").append(value[0]);
   429              }
   430          }
   431          
   432          return Utilities.toBase64(string.toString().substring(1).getBytes());
   433      }
   434      
   435  }








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