File Source: JPAWeblogManagerImpl.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.business.jpa;
    20  
    21  import java.util.ArrayList;
    22  import java.util.Calendar;
    23  import java.util.Collections;
    24  import java.util.Comparator;
    25  import java.util.Date;
    26  import java.util.Hashtable;
    27  import java.util.Iterator;
    28  import java.util.List;
    29  import java.util.Map;
    30  import java.text.SimpleDateFormat;
    31  import java.util.TreeMap;
    32  import java.sql.Timestamp;
    33  import javax.persistence.FlushModeType;
    34  import javax.persistence.NoResultException;
    35  import javax.persistence.Query;
    36  
    37  import org.apache.commons.collections.comparators.ReverseComparator;
    38  import org.apache.commons.lang.StringUtils;
    39  import org.apache.commons.logging.Log;
    40  import org.apache.commons.logging.LogFactory;
    41  import org.apache.roller.weblogger.business.jpa.JPAPersistenceStrategy;
    42  
    43  import org.apache.roller.weblogger.WebloggerException;
    44  import org.apache.roller.weblogger.business.Weblogger;
    45  import org.apache.roller.weblogger.business.WeblogManager;
    46  import org.apache.roller.weblogger.pojos.WeblogEntryComment;
    47  import org.apache.roller.weblogger.pojos.WeblogHitCount;
    48  import org.apache.roller.weblogger.pojos.WeblogReferrer;
    49  import org.apache.roller.weblogger.pojos.StatCount;
    50  import org.apache.roller.weblogger.pojos.TagStat;
    51  import org.apache.roller.weblogger.pojos.TagStatComparator;
    52  import org.apache.roller.weblogger.pojos.TagStatCountComparator;
    53  import org.apache.roller.weblogger.pojos.WeblogCategory;
    54  import org.apache.roller.weblogger.pojos.WeblogEntry;
    55  import org.apache.roller.weblogger.pojos.WeblogEntryTagAggregate;
    56  import org.apache.roller.weblogger.pojos.WeblogEntryTag;
    57  import org.apache.roller.weblogger.pojos.Weblog;
    58  import org.apache.roller.weblogger.pojos.WeblogEntryAttribute;
    59  import org.apache.roller.weblogger.pojos.StatCountCountComparator;
    60  import org.apache.roller.weblogger.pojos.User;
    61  import org.apache.roller.util.DateUtil;
    62  
    63  /*
    64   * JPAWeblogManagerImpl.java
    65   *
    66   * Created on May 31, 2006, 4:08 PM
    67   *
    68   */
    69  @com.google.inject.Singleton
    70  public class JPAWeblogManagerImpl implements WeblogManager {
    71      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.business.jpa.JPAWeblogManagerImpl__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              *    reverseComparator == &new ReverseComparator(JPAWeblogManagerImpl__static_init#1)
              *    init'ed(statCountCountReverseComparator)
              *    init'ed(tagStatCountReverseComparator)
              *    tagStatNameComparator == &new TagStatComparator(JPAWeblogManagerImpl__static_init#2)
              *    new ReverseComparator(JPAWeblogManagerImpl__static_init#1) num objects == 1
              *    new TagStatComparator(JPAWeblogManagerImpl__static_init#2) num objects == 1
              */
    72      protected static Log log = LogFactory.getLog(
    73              JPAWeblogManagerImpl.class);
    74      
    75      private final Weblogger roller;
    76      private final JPAPersistenceStrategy strategy;
    77      
    78      // cached mapping of entryAnchors -> entryIds
    79      private Hashtable entryAnchorToIdMap = new Hashtable();
    80      
    81      /* inline creation of reverse comparator, anonymous inner class */
    82      private static final Comparator reverseComparator = new ReverseComparator();
    83      
    84      private static final Comparator tagStatNameComparator = new TagStatComparator();
    85      
    86      private static final Comparator tagStatCountReverseComparator =
    87              Collections.reverseOrder(TagStatCountComparator.getInstance());
    88      
    89      private static final Comparator statCountCountReverseComparator =
    90              Collections.reverseOrder(StatCountCountComparator.getInstance());
    91      
    92      
    93      @com.google.inject.Inject
             /* 
    P/P       *  Method: void org.apache.roller.weblogger.business.jpa.JPAWeblogManagerImpl(Weblogger, JPAPersistenceStrategy)
              * 
              *  Preconditions:
              *    log != null
              * 
              *  Postconditions:
              *    this.entryAnchorToIdMap == &new Hashtable(JPAWeblogManagerImpl#1)
              *    this.roller == roller
              *    init'ed(this.roller)
              *    this.strategy == strategy
              *    init'ed(this.strategy)
              *    new Hashtable(JPAWeblogManagerImpl#1) num objects == 1
              */
    94      protected JPAWeblogManagerImpl(Weblogger roller, JPAPersistenceStrategy strategy) {
    95          log.debug("Instantiating JPA Weblog Manager");
    96          this.roller = roller;
    97          this.strategy = strategy;
    98      }
    99      
   100      /**
   101       * @inheritDoc
   102       */
   103      public void saveWeblogCategory(WeblogCategory cat) throws WebloggerException {
                 /* 
    P/P           *  Method: void saveWeblogCategory(WeblogCategory)
                  * 
                  *  Preconditions:
                  *    cat != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    getUserManager(...).strategy.emf@104 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@113 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWebsite(...)@118 != null
                  * 
                  *  Test Vectors:
                  *    javax.persistence.EntityManager:find(...)@216: Inverse{null}, Addr_Set{null}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@111: Addr_Set{null}, Inverse{null}
                  */
   104          boolean exists = getWeblogCategory(cat.getId()) != null;
   105          if (!exists) {
+  106              if (isDuplicateWeblogCategoryName(cat)) {
   107                  throw new WebloggerException("Duplicate category name, cannot save category");
   108              }
   109              // Newly added object. If it has a parent,
   110              // maintain relationship from both sides
   111              WeblogCategory parent = cat.getParent();
   112              if(parent != null) {
   113                  parent.getWeblogCategories().add(cat);
   114              }
   115          }
   116          
   117          // update weblog last modified date.  date updated by saveWebsite()
   118          roller.getUserManager().saveWebsite(cat.getWebsite());        
   119          this.strategy.store(cat);
   120      }
   121      
   122      /**
   123       * @inheritDoc
   124       */
   125      public void removeWeblogCategory(WeblogCategory cat)
   126      throws WebloggerException {
                 /* 
    P/P           *  Method: void removeWeblogCategory(WeblogCategory)
                  * 
                  *  Preconditions:
                  *    cat != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    getUserManager(...).strategy.emf@132 != null
                  *    java.util.List:size(...)@127 <= 0
                  *    org.apache.roller.weblogger.pojos.Weblog:getBloggerCategory(...)@140 != null
                  *    org.apache.roller.weblogger.pojos.Weblog:getDefaultCategory(...)@146 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@136 != null
                  *    ...
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@140: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@146: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@134: Addr_Set{null}, Inverse{null}
                  */
   127          if(cat.retrieveWeblogEntries(true).size() > 0) {
   128              throw new WebloggerException("Cannot remove category with entries");
   129          }
   130          
   131          // remove cat
   132          this.strategy.remove(cat);
   133          //relationship management for the other side
   134          WeblogCategory parent = cat.getParent();
   135          if(parent != null) {
   136              parent.getWeblogCategories().remove(cat);
   137          }
   138          
   139          // update website default cats if needed
   140          if(cat.getWebsite().getBloggerCategory().equals(cat)) {
   141              WeblogCategory rootCat = this.getRootWeblogCategory(cat.getWebsite());
   142              cat.getWebsite().setBloggerCategory(rootCat);
   143              this.strategy.store(cat.getWebsite());
   144          }
   145          
   146          if(cat.getWebsite().getDefaultCategory().equals(cat)) {
   147              WeblogCategory rootCat = this.getRootWeblogCategory(cat.getWebsite());
   148              cat.getWebsite().setDefaultCategory(rootCat);
   149              this.strategy.store(cat.getWebsite());
   150          }
   151          
   152          // update weblog last modified date.  date updated by saveWebsite()
   153          roller.getUserManager().saveWebsite(
   154                  cat.getWebsite());
   155      }
   156      
   157      /**
   158       * @inheritDoc
   159       */
   160      public void moveWeblogCategory(WeblogCategory srcCat, WeblogCategory destCat)
   161      throws WebloggerException {
   162          
   163          // TODO: this check should be made before calling this method?
                 /* 
    P/P           *  Method: void moveWeblogCategory(WeblogCategory, WeblogCategory)
                  * 
                  *  Preconditions:
                  *    destCat != null
                  *    log != null
                  *    srcCat != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@164 == 0
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@175 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@178 != null
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@180: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@173: Addr_Set{null}, Inverse{null}
                  */
   164          if (destCat.descendentOf(srcCat)) {
   165              throw new WebloggerException(
   166                      "ERROR cannot move parent category into it's own child");
   167          }
   168          
   169          log.debug("Moving category "+srcCat.getPath() +
   170                  " under "+destCat.getPath());
   171          
   172          
   173          WeblogCategory oldParent = srcCat.getParent();
   174          if(oldParent != null) {
   175              oldParent.getWeblogCategories().remove(srcCat);
   176          }
   177          srcCat.setParent(destCat);
   178          destCat.getWeblogCategories().add(srcCat);
   179          
   180          if("/".equals(destCat.getPath())) {
   181              srcCat.setPath("/"+srcCat.getName());
   182          } else {
   183              srcCat.setPath(destCat.getPath() + "/" + srcCat.getName());
   184          }
   185          saveWeblogCategory(srcCat);
   186          
   187          // the main work to be done for a category move is to update the
   188          // path attribute of the category and all descendent categories
   189          updatePathTree(srcCat);
   190      }
   191      
   192      
   193      // updates the paths of all descendents of the given category
   194      private void updatePathTree(WeblogCategory cat)
   195      throws WebloggerException {
   196          
                 /* 
    P/P           *  Method: void updatePathTree(WeblogCategory)
                  * 
                  *  Preconditions:
                  *    cat != null
                  *    log != null
                  *    (soft) this.roller != null
                  *    (soft) this.roller.userManager != null
                  *    (soft) this.roller.userManager.strategy != null
                  *    (soft) this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@202 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@200 != null
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@207: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@201: {0}, {1}
                  */
   197          log.debug("Updating path tree for category "+cat.getPath());
   198          
   199          WeblogCategory childCat = null;
   200          Iterator childCats = cat.getWeblogCategories().iterator();
   201          while(childCats.hasNext()) {
   202              childCat = (WeblogCategory) childCats.next();
   203              
   204              log.debug("OLD child category path was "+childCat.getPath());
   205              
   206              // update path and save
   207              if("/".equals(cat.getPath())) {
   208                  childCat.setPath("/" + childCat.getName());
   209              } else {
   210                  childCat.setPath(cat.getPath() + "/" + childCat.getName());
   211              }
   212              saveWeblogCategory(childCat);
   213              
   214              log.debug("NEW child category path is "+ childCat.getPath());
   215              
   216              // then make recursive call to update this cats children
   217              updatePathTree(childCat);
   218          }
   219      }
   220      
   221      /**
   222       * @inheritDoc
   223       */
   224      public void moveWeblogCategoryContents(WeblogCategory srcCat,
   225              WeblogCategory destCat)
   226              throws WebloggerException {
   227          
   228          // TODO: this check should be made before calling this method?
                 /* 
    P/P           *  Method: void moveWeblogCategoryContents(WeblogCategory, WeblogCategory)
                  * 
                  *  Preconditions:
                  *    destCat != null
                  *    srcCat != null
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@241 != null
                  *    org.apache.roller.weblogger.pojos.Weblog:getBloggerCategory(...)@257 != null
                  *    org.apache.roller.weblogger.pojos.Weblog:getDefaultCategory(...)@250 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@229 == 0
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getId(...)@250 != null
                  *    ...
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@250: {1}, {0}
                  *    java.lang.String:equals(...)@257: {1}, {0}
                  *    java.util.Iterator:hasNext(...)@240: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@250: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:descendentOf(...)@257: {0}, {1}
                  */
   229          if (destCat.descendentOf(srcCat)) {
   230              throw new WebloggerException(
   231                      "ERROR cannot move parent category into it's own child");
   232          }
   233          
   234          // get all entries in category and subcats
   235          List results = srcCat.retrieveWeblogEntries(true);
   236          
   237          // Loop through entries in src cat, assign them to dest cat
   238          Iterator iter = results.iterator();
   239          Weblog website = destCat.getWebsite();
   240          while (iter.hasNext()) {
   241              WeblogEntry entry = (WeblogEntry) iter.next();
   242              entry.setCategory(destCat);
   243              entry.setWebsite(website);
   244              this.strategy.store(entry);
   245          }
   246          
   247          // Make sure website's default and bloggerapi categories
   248          // are valid after the move
   249          
   250          if (srcCat.getWebsite().getDefaultCategory().getId()
   251          .equals(srcCat.getId())
   252          || srcCat.getWebsite().getDefaultCategory().descendentOf(srcCat)) {
   253              srcCat.getWebsite().setDefaultCategory(destCat);
   254              this.strategy.store(srcCat.getWebsite());
   255          }
   256          
   257          if (srcCat.getWebsite().getBloggerCategory().getId()
   258          .equals(srcCat.getId())
   259          || srcCat.getWebsite().getBloggerCategory().descendentOf(srcCat)) {
   260              srcCat.getWebsite().setBloggerCategory(destCat);
   261              this.strategy.store(srcCat.getWebsite());
   262          }
   263      }
   264      
   265      /**
   266       * @inheritDoc
   267       */
   268      public void saveComment(WeblogEntryComment comment) throws WebloggerException {
                 /* 
    P/P           *  Method: void saveComment(WeblogEntryComment)
                  * 
                  *  Preconditions:
                  *    comment != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    getUserManager(...).strategy.emf@269 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@272 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntryComment:getWeblogEntry(...)@272 != null
                  */
   269          this.strategy.store(comment);
   270          
   271          // update weblog last modified date.  date updated by saveWebsite()
   272          roller.getUserManager()
   273          .saveWebsite(comment.getWeblogEntry().getWebsite());
   274      }
   275      
   276      /**
   277       * @inheritDoc
   278       */
   279      public void removeComment(WeblogEntryComment comment) throws WebloggerException {
                 /* 
    P/P           *  Method: void removeComment(WeblogEntryComment)
                  * 
                  *  Preconditions:
                  *    comment != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    getUserManager(...).strategy.emf@280 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@283 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntryComment:getWeblogEntry(...)@283 != null
                  */
   280          this.strategy.remove(comment);
   281          
   282          // update weblog last modified date.  date updated by saveWebsite()
   283          roller.getUserManager()
   284          .saveWebsite(comment.getWeblogEntry().getWebsite());
   285      }
   286      
   287      /**
   288       * @inheritDoc
   289       */
   290      // TODO: perhaps the createAnchor() and queuePings() items should go outside this method?
   291      public void saveWeblogEntry(WeblogEntry entry) throws WebloggerException {
   292          
                 /* 
    P/P           *  Method: void saveWeblogEntry(WeblogEntry)
                  * 
                  *  Preconditions:
                  *    entry != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) org/apache/roller/weblogger/business/WebloggerFactory.webloggerProvider != null
                  *    (soft) org/apache/roller/weblogger/business/WebloggerFactory.webloggerProvider.webloggerInstance != null
                  *    (soft) org/apache/roller/weblogger/business/jpa/JPAAutoPingManagerImpl.logger != null
                  *    (soft) org/apache/roller/weblogger/business/jpa/JPAPingQueueManagerImpl.log != null
                  *    (soft) org/apache/roller/weblogger/config/WebloggerRuntimeConfig.log != null
                  *    (soft) org/apache/roller/weblogger/pojos/AutoPing.pcInheritedFieldCount <= 232-3
                  *    (soft) this.roller != null
                  *    ...
                  * 
                  *  Presumptions:
                  *    getAutopingManager(...).strategy.emf@318 != null
                  *    getUserManager(...).strategy.emf@318 != null
                  *    java.lang.System:currentTimeMillis(...)@310 <= 18_446_744_073_709_491_615
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getAddedTags(...)@297 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getAnchor(...)@293 != null
                  *    ...
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@293: {0}, {1}
                  *    java.lang.String:equals(...)@310: {0}, {1}
                  *    java.sql.Timestamp:after(...)@310: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@297: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@302: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getAnchor(...)@293: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:isPublished(...)@321: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:isPublished(...)@326: {0}, {1}
                  */
   293          if (entry.getAnchor() == null || entry.getAnchor().trim().equals("")) {
   294              entry.setAnchor(this.createAnchor(entry));
   295          }
   296          
   297          for(Iterator it = entry.getAddedTags().iterator(); it.hasNext();) {
   298              String name = (String) it.next();
   299              updateTagCount(name, entry.getWebsite(), 1);
   300          }
   301          
   302          for(Iterator it = entry.getRemovedTags().iterator(); it.hasNext();) {
   303              String name = (String) it.next();
   304              updateTagCount(name, entry.getWebsite(), -1);
   305          }
   306          
   307          // if the entry was published to future, set status as SCHEDULED
   308          // we only consider an entry future published if it is scheduled
   309          // more than 1 minute into the future
   310          if ("PUBLISHED".equals(entry.getStatus()) &&
   311                  entry.getPubTime().after(new Date(System.currentTimeMillis() + 60000))) {
   312              entry.setStatus(WeblogEntry.SCHEDULED);
   313          }
   314          
   315          // Store value object (creates new or updates existing)
   316          entry.setUpdateTime(new Timestamp(new Date().getTime()));
   317          
   318          this.strategy.store(entry);
   319          
   320          // update weblog last modified date.  date updated by saveWebsite()
   321          if(entry.isPublished()) {
   322              roller.getUserManager()
   323              .saveWebsite(entry.getWebsite());
   324          }
   325          
   326          if(entry.isPublished()) {
   327              // Queue applicable pings for this update.
   328              roller.getAutopingManager()
   329              .queueApplicableAutoPings(entry);
   330          }
   331      }
   332      
   333      /**
   334       * @inheritDoc
   335       */
   336      public void removeWeblogEntry(WeblogEntry entry)
   337      throws WebloggerException {
   338          
                 /* 
    P/P           *  Method: void removeWeblogEntry(WeblogEntry)
                  * 
                  *  Preconditions:
                  *    entry != null
                  *    this.entryAnchorToIdMap != null
                  *    this.roller != null
                  *    this.roller.userManager != null
                  *    this.roller.userManager.strategy != null
                  *    this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    getUserManager(...).strategy.emf@390 != null
                  *    java.util.Iterator:next(...)@346 != null
                  *    java.util.Iterator:next(...)@371 != null
                  *    javax.persistence.Query:getResultList(...)@344 != null
                  *    javax.persistence.Query:getResultList(...)@924 != null
                  *    ...
                  * 
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@345: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@364: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@370: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@380: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getEntryAttributes(...)@379: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getTags(...)@369: Addr_Set{null}, Inverse{null}
                  */
   339          String entryAnchor = entry.getAnchor();
   340          Weblog website = entry.getWebsite();
   341          
   342          Query q = strategy.getNamedQuery("WeblogReferrer.getByWeblogEntry");
   343          q.setParameter(1, entry);
   344          List referers = q.getResultList();
   345          for (Iterator iter = referers.iterator(); iter.hasNext();) {
   346              WeblogReferrer referer = (WeblogReferrer) iter.next();
   347              this.strategy.remove(referer.getClass(), referer.getId());
   348          }
   349          // TODO: can we eliminate this unnecessary flush with OpenJPA 1.0
   350          this.strategy.flush(); 
   351         
   352          // remove comments
   353          List comments = getComments(
   354                  null,  // website
   355                  entry,
   356                  null,  // search String
   357                  null,  // startDate
   358                  null,  // endDate
   359                  null,  // status
   360                  true,  // reverse chrono order (not that it matters)
   361                  0,     // offset
   362                  -1);   // no limit
   363          Iterator commentsIT = comments.iterator();
   364          while (commentsIT.hasNext()) {
   365              this.strategy.remove((WeblogEntryComment) commentsIT.next());
   366          }
   367          
   368          // remove tags aggregates
   369          if (entry.getTags() != null) {
   370              for (Iterator it = entry.getTags().iterator(); it.hasNext(); ) {
   371                  WeblogEntryTag tag = (WeblogEntryTag) it.next();
   372                  updateTagCount(tag.getName(), entry.getWebsite(), -1);
   373                  it.remove();
   374                  this.strategy.remove(tag);
   375              }
   376          }
   377          
   378          // remove attributes
   379          if (entry.getEntryAttributes() != null) {
   380              for (Iterator it = entry.getEntryAttributes().iterator(); it.hasNext(); ) {
   381                  WeblogEntryAttribute att = (WeblogEntryAttribute) it.next();
   382                  it.remove();
   383                  this.strategy.remove(att);
   384              }
   385          }
   386          // TODO: can we eliminate this unnecessary flush with OpenJPA 1.0
   387          this.strategy.flush(); 
   388          
   389          // remove entry
   390          this.strategy.remove(entry);
   391          
   392          // update weblog last modified date. date updated by saveWebsite()
   393          roller.getUserManager().saveWebsite(website);
   394          
   395          // remove entry from cache mapping
   396          this.entryAnchorToIdMap.remove(website.getHandle() + ":" + entryAnchor);
   397      }
   398      
   399      public List getNextPrevEntries(WeblogEntry current, String catName,
   400              String locale, int maxEntries, boolean next)
   401              throws WebloggerException {
                 /* 
    P/P           *  Method: List getNextPrevEntries(WeblogEntry, String, String, int, bool)
                  * 
                  *  Preconditions:
                  *    current != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@407 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@432 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    catName: Addr_Set{null}, Inverse{null}
                  *    locale: Addr_Set{null}, Inverse{null}
                  *    next: {0}, {1}
                  *    java.lang.String:equals(...)@406: {1}, {0}
                  *    java.lang.String:equals(...)@431: {1}, {0}
                  */
   402          Query query = null;
   403          List results = null;
   404          WeblogCategory category = null;
   405          
   406          if (catName != null && !catName.trim().equals("/")) {
+  407              category = getWeblogCategoryByPath(current.getWebsite(), null,
   408                      catName);
   409          }
   410                  
   411          List params = new ArrayList();
   412          int size = 0;
   413          StringBuffer queryString = new StringBuffer();
   414          StringBuffer whereClause = new StringBuffer();
   415          queryString.append("SELECT e FROM WeblogEntry e WHERE ");
   416                       
   417          params.add(size++, current.getWebsite());
   418          whereClause.append("e.website = ?" + size); 
   419          
   420          params.add(size++, WeblogEntry.PUBLISHED);
   421          whereClause.append(" AND e.status = ?" + size);
   422                  
   423          if (next) {
   424              params.add(size++, current.getPubTime());
   425              whereClause.append(" AND e.pubTime > ?" + size);
   426          } else {
   427              params.add(size++, current.getPubTime());
   428              whereClause.append(" AND e.pubTime < ?" + size);
   429          }
   430          
   431          if (catName != null && !catName.trim().equals("/")) {
   432              category = getWeblogCategoryByPath(current.getWebsite(), catName);
   433              if (category != null) {
   434                  params.add(size++, category);
   435                  whereClause.append(" AND e.category = ?" + size);
   436              } else {
+  437                  throw new WebloggerException("Cannot find category: " + catName);
   438              } 
   439          }
   440          
   441          if(locale != null) {
   442              params.add(size++, locale + '%');
   443              whereClause.append(" AND e.locale like ?" + size);
   444          }
   445          
   446          if (next) {
   447              whereClause.append(" ORDER BY e.pubTime ASC");
   448          } else {
   449              whereClause.append(" ORDER BY e.pubTime DESC");
   450          }
   451          query = strategy.getDynamicQuery(queryString.toString() + whereClause.toString());
   452          for (int i=0; i<params.size(); i++) {
   453              query.setParameter(i+1, params.get(i));
   454          }
   455          query.setMaxResults(maxEntries);
   456          
   457          return query.getResultList();
   458      }
   459      
   460      /**
   461       * @inheritDoc
   462       */
   463      public WeblogCategory getRootWeblogCategory(Weblog website)
   464      throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogCategory getRootWeblogCategory(Weblog)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   465          if (website == null)
   466              throw new WebloggerException("website is null");
   467          
   468          Query q = strategy.getNamedQuery(
   469                  "WeblogCategory.getByWebsite&ParentNull");
   470          q.setParameter(1, website);
   471          try {
   472              return (WeblogCategory)q.getSingleResult();
   473          } catch (NoResultException e) {
   474              return null;
   475          }
   476      }
   477      
   478      /**
   479       * @inheritDoc
   480       */
   481      public List getWeblogCategories(Weblog website, boolean includeRoot)
   482      throws WebloggerException {
                 /* 
    P/P           *  Method: List getWeblogCategories(Weblog, bool)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    includeRoot: {0}, {1}
                  */
   483          if (website == null)
   484              throw new WebloggerException("website is null");
   485          
   486          if (includeRoot) return getWeblogCategories(website);
   487          
   488          Query q = strategy.getNamedQuery(
   489                  "WeblogCategory.getByWebsite&ParentNotNull");
   490          q.setParameter(1, website);
   491          return q.getResultList();
   492      }
   493      
   494      /**
   495       * @inheritDoc
   496       */
   497      public List getWeblogCategories(Weblog website)
   498      throws WebloggerException {
                 /* 
    P/P           *  Method: List getWeblogCategories(Weblog)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   499          if (website == null)
   500              throw new WebloggerException("website is null");
   501          
   502          Query q = strategy.getNamedQuery(
   503                  "WeblogCategory.getByWebsite");
   504          q.setParameter(1, website);
   505          return q.getResultList();
   506      }
   507      
   508      /**
   509       * @inheritDoc
   510       */
   511      public List getWeblogEntries(
   512              Weblog website,
   513              User    user,
   514              Date        startDate,
   515              Date        endDate,
   516              String      catName,
   517              List        tags,
   518              String      status,
   519              String      text,
   520              String      sortby,
   521              String      sortOrder,
   522              String      locale,
   523              int         offset,
   524              int         length) throws WebloggerException {
   525          
                 /* 
    P/P           *  Method: List getWeblogEntries(Weblog, User, Date, Date, String, List, String, String, String, String, String, int, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    init'ed(java.lang.Boolean.TRUE)
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    endDate: Addr_Set{null}, Inverse{null}
                  *    length: {-1}, {-231..-2, 0..232-1}
                  *    locale: Addr_Set{null}, Inverse{null}
                  *    offset: {0}, {-231..-1, 1..232-1}
                  *    sortOrder: Addr_Set{null}, Inverse{null}
                  *    sortby: Addr_Set{null}, Inverse{null}
                  *    startDate: Addr_Set{null}, Inverse{null}
                  *    status: Addr_Set{null}, Inverse{null}
                  *    tags: Addr_Set{null}, Inverse{null}
                  *    text: Addr_Set{null}, Inverse{null}
                  *    ...
                  */
   526          WeblogCategory cat = null;
   527          if (StringUtils.isNotEmpty(catName) && website != null) {
   528              cat = getWeblogCategoryByPath(website, catName);
   529              if (cat == null) catName = null;
   530          }
   531          if (catName != null && catName.trim().equals("/")) {
   532              catName = null;
   533          }
   534          
   535          List params = new ArrayList();
   536          int size = 0;
   537          StringBuffer queryString = new StringBuffer();
   538          
   539          //queryString.append("SELECT e FROM WeblogEntry e WHERE ");
   540          if (tags == null || tags.size()==0) {
   541              queryString.append("SELECT e FROM WeblogEntry e WHERE ");
   542          } else {
   543              queryString.append("SELECT e FROM WeblogEntry e JOIN e.tags t WHERE ");
   544              queryString.append("(");
   545              for(int i = 0; i < tags.size(); i++) {
   546                  if (i != 0) queryString.append(" OR ");
   547                  params.add(size++, tags.get(i));
   548                  queryString.append(" t.name = ?").append(size);                
   549              }
   550              queryString.append(") AND ");
   551          }
   552          
   553          if (website != null) {
+  554              params.add(size++, website.getId());
   555              queryString.append("e.website.id = ?").append(size);
   556          } else {
+  557              params.add(size++, Boolean.TRUE);
   558              queryString.append("e.website.enabled = ?").append(size);
   559          }
   560          
   561          /*if (tags != null && tags.size() > 0) {
   562              // A JOIN with WeblogEntryTag in parent quert will cause a DISTINCT in SELECT clause
   563              // WeblogEntry has a clob field and many databases do not link DISTINCT for CLOB fields
   564              // Hence as a workaround using corelated EXISTS query.
   565              queryString.append(" AND EXISTS (SELECT t FROM WeblogEntryTag t WHERE "
   566                      + " t.weblogEntry = e AND t.name IN (");
   567              final String PARAM_SEPERATOR = ", ";
   568              for(int i = 0; i < tags.size(); i++) {
   569                  params.add(size++, tags.get(i));
   570                  queryString.append("?").append(size).append(PARAM_SEPERATOR);
   571              }
   572              // Remove the trailing PARAM_SEPERATOR
   573              queryString.delete(queryString.length() - PARAM_SEPERATOR.length(),
   574                      queryString.length());
   575  
   576              // Close the brace FOR IN clause and EXIST clause
   577              queryString.append(" ) )");
   578          }*/
   579  
   580          if (user != null) {
+  581              params.add(size++, user.getId());
   582              queryString.append(" AND e.creator.id = ?").append(size);
   583          }
   584          
   585          if (startDate != null) {
   586              Timestamp start = new Timestamp(startDate.getTime());
+  587              params.add(size++, start);
   588              queryString.append(" AND e.pubTime >= ?").append(size);
   589          }
   590          
   591          if (endDate != null) {
   592              Timestamp end = new Timestamp(endDate.getTime());
+  593              params.add(size++, end);
   594              queryString.append(" AND e.pubTime <= ?").append(size);
   595          }
   596          
+  597          if (cat != null && website != null) {
+  598              params.add(size++, cat.getId());
   599              queryString.append(" AND e.category.id = ?").append(size);
   600          }
   601                  
   602          if (status != null) {
+  603              params.add(size++, status);
   604              queryString.append(" AND e.status = ?").append(size);
   605          }
   606          
   607          if (locale != null) {
+  608              params.add(size++, locale + '%');
   609              queryString.append(" AND e.locale like ?").append(size);
   610          }
   611          
   612          if (text != null) {
+  613              params.add(size++, '%' + text + '%');
   614              queryString.append(" AND ( e.text LIKE ?").append(size);
   615              queryString.append("    OR e.summary LIKE ? ").append(size);
   616              queryString.append("    OR e.title LIKE ?").append(size);
   617              queryString.append(") ");
   618          }
   619          
   620          if (sortby != null && sortby.equals("updateTime")) {
   621              queryString.append(" ORDER BY e.updateTime ");
   622          } else {
   623              queryString.append(" ORDER BY e.pubTime ");
   624          }
   625          
   626          if (sortOrder != null && sortOrder.equals(ASCENDING)) {
   627              queryString.append("ASC ");
   628          } else {
   629              queryString.append("DESC ");
   630          }
   631          
   632          
   633          Query query = strategy.getDynamicQuery(queryString.toString());
   634          for (int i=0; i<params.size(); i++) {
   635              query.setParameter(i+1, params.get(i));
   636          }
   637          
   638          if (offset != 0) {
   639              query.setFirstResult(offset);
   640          }
   641          if (length != -1) {
   642              query.setMaxResults(length);
   643          }
   644          
   645          return query.getResultList();
   646      }
   647      
   648      /**
   649       * @inheritDoc
   650       */
   651      public List getWeblogEntriesPinnedToMain(Integer max)
   652      throws WebloggerException {
                 /* 
    P/P           *  Method: List getWeblogEntriesPinnedToMain(Integer)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    init'ed(java.lang.Boolean.TRUE)
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    max: Addr_Set{null}, Inverse{null}
                  */
   653          Query query = strategy.getNamedQuery(
   654                  "WeblogEntry.getByPinnedToMain&statusOrderByPubTimeDesc");
   655          query.setParameter(1, Boolean.TRUE);
   656          query.setParameter(2, WeblogEntry.PUBLISHED);
   657          if (max != null) {
   658              query.setMaxResults(max.intValue());
   659          }
   660          return query.getResultList();
   661      }
   662      
   663      public void removeWeblogEntryAttribute(String name, WeblogEntry entry)
   664      throws WebloggerException {
                 /* 
    P/P           *  Method: void removeWeblogEntryAttribute(String, WeblogEntry)
                  * 
                  *  Preconditions:
                  *    entry != null
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@666 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getEntryAttributes(...)@665 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntryAttribute:getName(...)@667 != null
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@667: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@665: {0}, {1}
                  */
   665          for (Iterator it = entry.getEntryAttributes().iterator(); it.hasNext();) {
   666              WeblogEntryAttribute entryAttribute = (WeblogEntryAttribute) it.next();
   667              if (entryAttribute.getName().equals(name)) {
   668                  //Remove it from database
   669                  this.strategy.remove(entryAttribute);
   670                  //Remove it from the collection
   671                  it.remove();
   672              }
   673          }
   674      }
   675      
   676      public void removeWeblogEntryTag(String name, WeblogEntry entry)
   677      throws WebloggerException {
                 /* 
    P/P           *  Method: void removeWeblogEntryTag(String, WeblogEntry)
                  * 
                  *  Preconditions:
                  *    entry != null
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@679 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntry:getTags(...)@678 != null
                  *    org.apache.roller.weblogger.pojos.WeblogEntryTag:getName(...)@680 != null
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@680: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@678: {0}, {1}
                  */
   678          for (Iterator it = entry.getTags().iterator(); it.hasNext();) {
   679              WeblogEntryTag tag = (WeblogEntryTag) it.next();
   680              if (tag.getName().equals(name)) {
   681                  //Call back the entity to adjust its internal state
   682                  entry.onRemoveTag(name);
   683                  //Remove it from database
   684                  this.strategy.remove(tag);
   685                  //Remove it from the collection
   686                  it.remove();
   687              }
   688          }
   689      }
   690      
   691      /**
   692       * @inheritDoc
   693       */
   694      public WeblogEntry getWeblogEntryByAnchor(Weblog website,
   695              String anchor) throws WebloggerException {
   696          
                 /* 
    P/P           *  Method: WeblogEntry getWeblogEntryByAnchor(Weblog, String)
                  * 
                  *  Preconditions:
                  *    anchor != null
                  *    this.entryAnchorToIdMap != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) log != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.util.Hashtable:containsKey(...)@708: {0}, {1}
                  *    javax.persistence.EntityManager:find(...)@216: Addr_Set{null}, Inverse{null}
                  */
   697          if (website == null)
   698              throw new WebloggerException("Website is null");
   699          
   700          if (anchor == null)
   701              throw new WebloggerException("Anchor is null");
   702          
   703          // mapping key is combo of weblog + anchor
   704          String mappingKey = website.getHandle()+":"+anchor;
   705          
   706          // check cache first
   707          // NOTE: if we ever allow changing anchors then this needs updating
   708          if(this.entryAnchorToIdMap.containsKey(mappingKey)) {
   709              
   710              WeblogEntry entry = this.getWeblogEntry((String) this.entryAnchorToIdMap.get(mappingKey));
   711              if(entry != null) {
   712                  log.debug("entryAnchorToIdMap CACHE HIT - "+mappingKey);
   713                  return entry;
   714              } else {
   715                  // mapping hit with lookup miss?  mapping must be old, remove it
   716                  this.entryAnchorToIdMap.remove(mappingKey);
   717              }
   718          }
   719          
   720          // cache failed, do lookup
   721          Query q = strategy.getNamedQuery(
   722                  "WeblogEntry.getByWebsite&AnchorOrderByPubTimeDesc");
   723          q.setParameter(1, website);
   724          q.setParameter(2, anchor);
   725          WeblogEntry entry = null;
   726          try {
   727              entry = (WeblogEntry)q.getSingleResult();
   728          } catch (NoResultException e) {
   729              entry = null;
   730          }
   731          
   732          // add mapping to cache
   733          if(entry != null) {
   734              log.debug("entryAnchorToIdMap CACHE MISS - "+mappingKey);
   735              this.entryAnchorToIdMap.put(mappingKey, entry.getId());
   736          }
   737          return entry;
   738      }
   739      
   740      /**
   741       * @inheritDoc
   742       */
   743      // TODO: this method should be removed and it's functionality moved to getWeblogEntries()
   744      public List getWeblogEntries(WeblogCategory cat, boolean subcats)
   745      throws WebloggerException {
                 /* 
    P/P           *  Method: List getWeblogEntries(WeblogCategory, bool)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) cat != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    subcats: {1}, {0}
                  */
   746          List results = null;
   747          
   748          if (!subcats) {
   749              Query q = strategy.getNamedQuery(
   750                      "WeblogEntry.getByStatus&Category");
   751              q.setParameter(1, WeblogEntry.PUBLISHED);
   752              q.setParameter(2, cat);
   753              results = q.getResultList();
   754          } else {
   755              Query q = strategy.getNamedQuery(
   756                      "WeblogEntry.getByStatus&Category.pathLike&Website");
   757              q.setParameter(1, WeblogEntry.PUBLISHED);
   758              q.setParameter(2, cat.getPath() + '%');
   759              q.setParameter(3, cat.getWebsite());
   760              results = q.getResultList();
   761          }
   762          
   763          return results;
   764      }
   765      
   766      /**
   767       * @inheritDoc
   768       */
   769      public String createAnchor(WeblogEntry entry) throws WebloggerException {
   770          // Check for uniqueness of anchor
                 /* 
    P/P           *  Method: String createAnchor(WeblogEntry)
                  * 
                  *  Preconditions:
                  *    entry != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    javax.persistence.Query:getResultList(...)@784 != null
                  * 
                  *  Postconditions:
                  *    java.lang.StringBuilder:toString(...)._tainted == 0
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.util.List:size(...)@786: {1..232-1}, {-231..0}
                  */
   771          String base = entry.createAnchorBase();
   772          String name = base;
   773          int count = 0;
   774          
   775          while (true) {
   776              if (count > 0) {
   777                  name = base + count;
   778              }
   779              
   780              Query q = strategy.getNamedQuery(
   781                      "WeblogEntry.getByWebsite&Anchor");
   782              q.setParameter(1, entry.getWebsite());
   783              q.setParameter(2, name);
   784              List results = q.getResultList();
   785              
   786              if (results.size() < 1) {
   787                  break;
   788              } else {
+  789                  count++;
   790              }
   791          }
   792          return name;
   793      }
   794      
   795      /**
   796       * @inheritDoc
   797       */
   798      public boolean isDuplicateWeblogCategoryName(WeblogCategory cat)
   799      throws WebloggerException {
   800          
   801          // ensure that no sibling categories share the same name
                 /* 
    P/P           *  Method: bool isDuplicateWeblogCategoryName(WeblogCategory)
                  * 
                  *  Preconditions:
                  *    cat != null
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWebsite(...)@804 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getParent(...)@802: Addr_Set{null}, Inverse{null}
                  */
   802          WeblogCategory parent = cat.getParent();
   803          if (null != parent) {
   804              return (getWeblogCategoryByPath(
   805                      cat.getWebsite(), cat.getPath()) != null);
   806          }
   807          
   808          return false;
   809      }
   810      
   811      /**
   812       * @inheritDoc
   813       */
   814      public boolean isWeblogCategoryInUse(WeblogCategory cat)
   815      throws WebloggerException {
   816          
                 /* 
    P/P           *  Method: bool isWeblogCategoryInUse(WeblogCategory)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) cat != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@827 != null
                  *    javax.persistence.Query:getResultList(...)@819 != null
                  *    org.apache.roller.weblogger.pojos.Weblog:getBloggerCategory(...)@833 != null
                  *    org.apache.roller.weblogger.pojos.Weblog:getDefaultCategory(...)@837 != null
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:getWeblogCategories(...)@825 != null
                  *    ...
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@826: {0}, {1}
                  *    java.util.List:size(...)@819: {-231..0}, {1..232-1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@833: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:equals(...)@837: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.WeblogCategory:isInUse(...)@828: {0}, {1}
                  */
   817          Query q = strategy.getNamedQuery("WeblogEntry.getByCategory");
   818          q.setParameter(1, cat);
   819          int entryCount = q.getResultList().size();
   820          
   821          if (entryCount > 0) {
   822              return true;
   823          }
   824          
   825          Iterator cats = cat.getWeblogCategories().iterator();
   826          while (cats.hasNext()) {
   827              WeblogCategory childCat = (WeblogCategory)cats.next();
   828              if (childCat.isInUse()) {
   829                  return true;
   830              }
   831          }
   832          
   833          if (cat.getWebsite().getBloggerCategory().equals(cat)) {
   834              return true;
   835          }
   836          
   837          if (cat.getWebsite().getDefaultCategory().equals(cat)) {
   838              return true;
   839          }
   840          
   841          return false;
   842      }
   843      
   844      /**
   845       * @inheritDoc
   846       */
   847      public List getComments(
   848              Weblog     website,
   849              WeblogEntry entry,
   850              String          searchString,
   851              Date            startDate,
   852              Date            endDate,
   853              String          status,
   854              boolean         reverseChrono,
   855              int             offset,
   856              int             length) throws WebloggerException {
   857          
                 /* 
    P/P           *  Method: List getComments(Weblog, WeblogEntry, String, Date, Date, String, bool, int, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    endDate: Addr_Set{null}, Inverse{null}
                  *    entry: Addr_Set{null}, Inverse{null}
                  *    length: {-1}, {-231..-2, 0..232-1}
                  *    offset: {0}, {-231..-1, 1..232-1}
                  *    reverseChrono: {0}, {1}
                  *    searchString: Addr_Set{null}, Inverse{null}
                  *    startDate: Addr_Set{null}, Inverse{null}
                  *    status: Addr_Set{null}, Inverse{null}
                  *    website: Addr_Set{null}, Inverse{null}
                  *    java.lang.String:equals(...)@892: {0}, {1}
                  *    ...
                  */
   858          List params = new ArrayList();
   859          int size = 0;
   860          StringBuffer queryString = new StringBuffer();
   861          queryString.append("SELECT c FROM WeblogEntryComment c ");
   862          
   863          StringBuffer whereClause = new StringBuffer();
   864          if (entry != null) {
   865              params.add(size++, entry);
   866              whereClause.append("c.weblogEntry = ?").append(size);
   867          } else if (website != null) {
   868              params.add(size++, website);
   869              whereClause.append("c.weblogEntry.website = ?").append(size);
   870          }
   871          
   872          if (searchString != null) {
   873              params.add(size++, "%" + searchString + "%");
   874              appendConjuctionToWhereclause(whereClause, "(c.url LIKE ?")
   875                  .append(size).append(" OR c.content LIKE ?").append(size).append(")");
   876          }
   877          
   878          if (startDate != null) {
   879              Timestamp start = new Timestamp(startDate.getTime());
   880              params.add(size++, start);
   881              appendConjuctionToWhereclause(whereClause, "c.postTime >= ?").append(size);
   882          }
   883          
   884          if (endDate != null) {
   885              Timestamp end = new Timestamp(endDate.getTime());
   886              params.add(size++, end);
   887              appendConjuctionToWhereclause(whereClause, "c.postTime <= ?").append(size);
   888          }
   889          
   890          if (status != null) {
   891              String comparisionOperator;
   892              if("ALL_IGNORE_SPAM".equals(status)) {
   893                  // we want all comments, except spam
   894                  // so that means where status != SPAM
   895                  status = WeblogEntryComment.SPAM;
   896                  comparisionOperator = " <> ";
   897              } else {
   898                  comparisionOperator = " = ";
   899              }
   900              params.add(size++, status);
   901              appendConjuctionToWhereclause(whereClause, "c.status ")
   902                  .append(comparisionOperator).append('?').append(size);
   903          }
   904          
   905          if(whereClause.length() != 0) {
   906              queryString.append(" WHERE ").append(whereClause);
   907          }
   908          if (reverseChrono) {
   909              queryString.append(" ORDER BY c.postTime DESC");
   910          } else {
   911              queryString.append(" ORDER BY c.postTime ASC");
   912          }
   913          
   914          Query query = strategy.getDynamicQuery(queryString.toString());
   915          if (offset != 0) {
   916              query.setFirstResult(offset);
   917          }
   918          if (length != -1) {
   919              query.setMaxResults(length);
   920          }
   921          for (int i=0; i<params.size(); i++) {
   922              query.setParameter(i+1, params.get(i));
   923          }
   924          return query.getResultList();
   925          
   926      }
   927      
   928      
   929      /**
   930       * @inheritDoc
   931       */
   932      public int removeMatchingComments(
   933              Weblog     website,
   934              WeblogEntry entry,
   935              String  searchString,
   936              Date    startDate,
   937              Date    endDate,
   938              String status) throws WebloggerException {
   939          
   940          // TODO dynamic bulk delete query: I'd MUCH rather use a bulk delete,
   941          // but MySQL says "General error, message from server: "You can't
   942          // specify target table 'roller_comment' for update in FROM clause"
   943          
                 /* 
    P/P           *  Method: int removeMatchingComments(Weblog, WeblogEntry, String, Date, Date, String)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.roller != null
                  *    (soft) this.roller.userManager != null
                  *    (soft) this.roller.userManager.strategy != null
                  *    (soft) this.roller.userManager.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@949 != null
                  *    javax.persistence.Query:getResultList(...)@924 != null
                  * 
                  *  Postconditions:
                  *    return_value >= 0
                  * 
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@948: {0}, {1}
                  */
   944          List comments = getComments(
   945                  website, entry, searchString, startDate, endDate,
   946                  status, true, 0, -1);
   947          int count = 0;
   948          for (Iterator it = comments.iterator(); it.hasNext();) {
   949              WeblogEntryComment comment = (WeblogEntryComment) it.next();
   950              removeComment(comment);
+  951              count++;
   952          }
   953          return count;
   954      }
   955      
   956      
   957      /**
   958       * @inheritDoc
   959       */
   960      public WeblogCategory getWeblogCategory(String id)
   961      throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogCategory getWeblogCategory(String)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   962          return (WeblogCategory) this.strategy.load(
   963                  WeblogCategory.class, id);
   964      }
   965      
   966      //--------------------------------------------- WeblogCategory Queries
   967      
   968      /**
   969       * @inheritDoc
   970       */
   971      public WeblogCategory getWeblogCategoryByPath(Weblog website,
   972              String categoryPath) throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogCategory getWeblogCategoryByPath(Weblog, String)
                  * 
                  *  Preconditions:
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  *    (soft) website != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
   973          return getWeblogCategoryByPath(website, null, categoryPath);
   974      }
   975      
   976      /**
   977       * @inheritDoc
   978       */
   979      // TODO: ditch this method in favor of getWeblogCategoryByPath(weblog, path)
   980      public WeblogCategory getWeblogCategoryByPath(Weblog website,
   981              WeblogCategory category, String path) throws WebloggerException {
   982          
                 /* 
    P/P           *  Method: WeblogCategory getWeblogCategoryByPath(Weblog, WeblogCategory, String)
                  * 
                  *  Preconditions:
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  *    (soft) website != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    path: Addr_Set{null}, Inverse{null}
                  *    java.lang.String:equals(...)@983: {0}, {1}
                  *    java.lang.String:startsWith(...)@989: {1}, {0}
                  */
   983          if (path == null || path.trim().equals("/")) {
   984              return getRootWeblogCategory(website);
   985          } else {
   986              String catPath = path;
   987              
   988              // all cat paths must begin with a '/'
   989              if(!catPath.startsWith("/")) {
   990                  catPath = "/"+catPath;
   991              }
   992              
   993              // now just do simple lookup by path
   994              Query q = strategy.getNamedQuery(
   995                      "WeblogCategory.getByPath&Website");
   996              q.setParameter(1, catPath);
   997              q.setParameter(2, website);
   998              try {
   999                  return (WeblogCategory)q.getSingleResult();
  1000              } catch (NoResultException e) {
  1001                  return null;
  1002              }
  1003          }
  1004      }
  1005      
  1006      /**
  1007       * @inheritDoc
  1008       */
  1009      public WeblogEntryComment getComment(String id) throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogEntryComment getComment(String)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1010          return (WeblogEntryComment) this.strategy.load(WeblogEntryComment.class, id);
  1011      }
  1012      
  1013      /**
  1014       * @inheritDoc
  1015       */
  1016      public WeblogEntry getWeblogEntry(String id) throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogEntry getWeblogEntry(String)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1017          return (WeblogEntry)strategy.load(WeblogEntry.class, id);
  1018      }
  1019      
  1020      /**
  1021       * @inheritDoc
  1022       */
  1023      public Map getWeblogEntryObjectMap(
  1024              Weblog website,
  1025              Date    startDate,
  1026              Date    endDate,
  1027              String  catName,
  1028              List    tags,
  1029              String  status,
  1030              String  locale,
  1031              int     offset,
  1032              int     length) throws WebloggerException {
                 /* 
    P/P           *  Method: Map getWeblogEntryObjectMap(Weblog, Date, Date, String, List, String, String, int, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    return_value == &new TreeMap(getWeblogEntryMap#1)
                  *    new TreeMap(getWeblogEntryMap#1) num objects == 1
                  */
  1033          return getWeblogEntryMap(
  1034                  website,
  1035                  startDate,
  1036                  endDate,
  1037                  catName,
  1038                  tags,
  1039                  status,
  1040                  false,
  1041                  locale,
  1042                  offset,
  1043                  length);
  1044      }
  1045      
  1046      /**
  1047       * @inheritDoc
  1048       */
  1049      public Map getWeblogEntryStringMap(
  1050              Weblog website,
  1051              Date    startDate,
  1052              Date    endDate,
  1053              String  catName,
  1054              List    tags,
  1055              String  status,
  1056              String  locale,
  1057              int     offset,
  1058              int     length
  1059              ) throws WebloggerException {
                 /* 
    P/P           *  Method: Map getWeblogEntryStringMap(Weblog, Date, Date, String, List, String, String, int, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    return_value == &new TreeMap(getWeblogEntryMap#1)
                  *    new TreeMap(getWeblogEntryMap#1) num objects == 1
                  */
  1060          return getWeblogEntryMap(
  1061                  website,
  1062                  startDate,
  1063                  endDate,
  1064                  catName,
  1065                  tags,
  1066                  status,
  1067                  true,
  1068                  locale,
  1069                  offset,
  1070                  length);
  1071      }
  1072      
  1073      private Map getWeblogEntryMap(
  1074              Weblog website,
  1075              Date    startDate,
  1076              Date    endDate,
  1077              String  catName,
  1078              List    tags,
  1079              String  status,
  1080              boolean stringsOnly,
  1081              String  locale,
  1082              int     offset,
  1083              int     length) throws WebloggerException {
  1084          
                 /* 
    P/P           *  Method: Map getWeblogEntryMap(Weblog, Date, Date, String, List, String, bool, String, int, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.Calendar:getInstance(...)@1102 != null
                  *    java.util.Iterator:next(...)@1109 != null
                  *    javax.persistence.Query:getResultList(...)@645 != null
                  *    org.apache.roller.util.DateUtil:get8charDateFormat(...)@1107 != null
                  * 
                  *  Postconditions:
                  *    return_value == &new TreeMap(getWeblogEntryMap#1)
                  *    new TreeMap(getWeblogEntryMap#1) num objects == 1
                  * 
                  *  Test Vectors:
                  *    stringsOnly: {0}, {1}
                  *    website: Addr_Set{null}, Inverse{null}
                  *    java.util.Iterator:hasNext(...)@1108: {0}, {1}
                  *    java.util.TreeMap:get(...)@1112: Inverse{null}, Addr_Set{null}
                  *    java.util.TreeMap:get(...)@1115: Inverse{null}, Addr_Set{null}
                  */
  1085          TreeMap map = new TreeMap(reverseComparator);
  1086          
  1087          List entries = getWeblogEntries( 
  1088                  website,
  1089                  null, // user
  1090                  startDate,
  1091                  endDate,
  1092                  catName,
  1093                  tags,
  1094                  status,
  1095                  null, // text
  1096                  null, // sortBy
  1097                  null, // sortOrder
  1098                  locale,
  1099                  offset,
  1100                  length);
  1101          
  1102          Calendar cal = Calendar.getInstance();
  1103          if (website != null) {
  1104              cal.setTimeZone(website.getTimeZoneInstance());
  1105          }
  1106          
  1107          SimpleDateFormat formatter = DateUtil.get8charDateFormat();
  1108          for (Iterator wbItr = entries.iterator(); wbItr.hasNext();) {
  1109              WeblogEntry entry = (WeblogEntry) wbItr.next();
  1110              Date sDate = DateUtil.getNoonOfDay(entry.getPubTime(), cal);
  1111              if (stringsOnly) {
  1112                  if (map.get(sDate) == null)
  1113                      map.put(sDate, formatter.format(sDate));
  1114              } else {
  1115                  List dayEntries = (List) map.get(sDate);
  1116                  if (dayEntries == null) {
  1117                      dayEntries = new ArrayList();
  1118                      map.put(sDate, dayEntries);
  1119                  }
  1120                  dayEntries.add(entry);
  1121              }
  1122          }
  1123          return map;
  1124      }
  1125      
  1126      /**
  1127       * @inheritDoc
  1128       */
  1129      public List getMostCommentedWeblogEntries(Weblog website,
  1130              Date startDate, Date endDate, int offset,
  1131              int length) throws WebloggerException {
                 /* 
    P/P           *  Method: List getMostCommentedWeblogEntries(Weblog, Date, Date, int, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@1176 != null
                  *    javax.persistence.Query:getResultList(...)@1173 != null
                  *    row.length@1176 >= 4
                  * 
                  *  Postconditions:
                  *    return_value == &new ArrayList(getMostCommentedWeblogEntries#8)
                  *    new ArrayList(getMostCommentedWeblogEntries#8) num objects == 1
                  * 
                  *  Test Vectors:
                  *    endDate: Inverse{null}, Addr_Set{null}
                  *    length: {-1}, {-231..-2, 0..232-1}
                  *    offset: {0}, {-231..-1, 1..232-1}
                  *    startDate: Addr_Set{null}, Inverse{null}
                  *    website: Addr_Set{null}, Inverse{null}
                  *    java.util.Iterator:hasNext(...)@1175: {0}, {1}
                  */
  1132          Query query = null;
  1133          List queryResults = null;        
  1134          if (endDate == null) endDate = new Date();
  1135          
  1136          if (website != null) {
  1137              if (startDate != null) {
  1138                  Timestamp start = new Timestamp(startDate.getTime());
  1139                  Timestamp end = new Timestamp(endDate.getTime());
  1140                  query = strategy.getNamedQuery(
  1141                          "WeblogEntryComment.getMostCommentedWeblogEntryByWebsite&EndDate&StartDate");
  1142                  query.setParameter(1, website);
  1143                  query.setParameter(2, end);
  1144                  query.setParameter(3, start);
  1145              } else {
  1146                  Timestamp end = new Timestamp(endDate.getTime());
  1147                  query = strategy.getNamedQuery(
  1148                          "WeblogEntryComment.getMostCommentedWeblogEntryByWebsite&EndDate");
  1149                  query.setParameter(1, website);
  1150                  query.setParameter(2, end);
  1151              }
  1152          } else {
  1153              if (startDate != null) {
  1154                  Timestamp start = new Timestamp(startDate.getTime());
  1155                  Timestamp end = new Timestamp(endDate.getTime());
  1156                  query = strategy.getNamedQuery(
  1157                          "WeblogEntryComment.getMostCommentedWeblogEntryByEndDate&StartDate");
  1158                  query.setParameter(1, end);
  1159                  query.setParameter(2, start);
  1160              } else {
  1161                  Timestamp end = new Timestamp(endDate.getTime());
  1162                  query = strategy.getNamedQuery(
  1163                          "WeblogEntryComment.getMostCommentedWeblogEntryByEndDate");
  1164                  query.setParameter(1, end);
  1165              }
  1166          }
  1167          if (offset != 0) {
  1168              query.setFirstResult(offset);
  1169          }
  1170          if (length != -1) {
  1171              query.setMaxResults(length);
  1172          }
  1173          queryResults = query.getResultList();
  1174          List results = new ArrayList();
  1175          for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
  1176              Object[] row = (Object[]) iter.next();
+ 1177              results.add(new StatCount(
  1178                      (String)row[1],                             // entry id
  1179                      (String)row[2],                             // entry anchor
  1180                      (String)row[3],                             // entry title
  1181                      "statCount.weblogEntryCommentCountType",    // stat desc
  1182                      ((Long)row[0]).longValue())); // count
  1183          }
  1184          // Original query ordered by desc count.
  1185          // JPA QL doesn't allow queries to be ordered by agregates; do it in memory
  1186          Collections.sort(results, statCountCountReverseComparator);
  1187          
  1188          return results;
  1189      }
  1190      
  1191      /**
  1192       * @inheritDoc
  1193       */
  1194      public WeblogEntry getNextEntry(WeblogEntry current,
  1195              String catName, String locale) throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogEntry getNextEntry(WeblogEntry, String, String)
                  * 
                  *  Preconditions:
                  *    current != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.util.List:size(...)@1198: {-231..0}, {1..232-1}
                  */
  1196          WeblogEntry entry = null;
  1197          List entryList = getNextPrevEntries(current, catName, locale, 1, true);
  1198          if (entryList != null && entryList.size() > 0) {
  1199              entry = (WeblogEntry)entryList.get(0);
  1200          }
  1201          return entry;
  1202      }
  1203      
  1204      /**
  1205       * @inheritDoc
  1206       */
  1207      public WeblogEntry getPreviousEntry(WeblogEntry current,
  1208              String catName, String locale) throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogEntry getPreviousEntry(WeblogEntry, String, String)
                  * 
                  *  Preconditions:
                  *    current != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    java.util.List:size(...)@1211: {-231..0}, {1..232-1}
                  */
  1209          WeblogEntry entry = null;
  1210          List entryList = getNextPrevEntries(current, catName, locale, 1, false);
  1211          if (entryList != null && entryList.size() > 0) {
  1212              entry = (WeblogEntry)entryList.get(0);
  1213          }
  1214          return entry;
  1215      }
  1216      
  1217      /**
  1218       * @inheritDoc
  1219       */
             /* 
    P/P       *  Method: void release()
              */
  1220      public void release() {}
  1221      
  1222      /**
  1223       * @inheritDoc
  1224       */
  1225      public void applyCommentDefaultsToEntries(Weblog website)
  1226      throws WebloggerException {
                 /* 
    P/P           *  Method: void applyCommentDefaultsToEntries(Weblog)
                  * 
                  *  Preconditions:
                  *    log != null
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    javax.persistence.EntityManager:createNamedQuery(...)@301 != null
                  * 
                  *  Test Vectors:
                  *    org.apache.commons.logging.Log:isDebugEnabled(...)@1227: {0}, {1}
                  */
  1227          if (log.isDebugEnabled()) {
  1228              log.debug("applyCommentDefaults");
  1229          }
  1230          
  1231          // TODO: Non-standard JPA bulk update, using parameter values in set clause
  1232          Query q = strategy.getNamedUpdate(
  1233                  "WeblogEntry.updateAllowComments&CommentDaysByWebsite");
  1234          q.setParameter(1, website.getDefaultAllowComments());
  1235          q.setParameter(2, new Integer(website.getDefaultCommentDays()));
  1236          q.setParameter(3, website);
  1237          q.executeUpdate();
  1238      }
  1239      
  1240      /**
  1241       * @inheritDoc
  1242       */
  1243      public List getPopularTags(Weblog website, Date startDate, int limit)
  1244      throws WebloggerException {
                 /* 
    P/P           *  Method: List getPopularTags(Weblog, Date, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    (int) (java.lang.Math:floor(...)@1299 + 1) in -231..232-1
                  *    java.util.Iterator:next(...)@1282 != null
                  *    java.util.Iterator:next(...)@1298 != null
                  *    javax.persistence.Query:getResultList(...)@1274 != null
                  *    row.length@1282 >= 2
                  * 
                  *  Postconditions:
                  *    return_value == &new ArrayList(getPopularTags#3)
                  *    new ArrayList(getPopularTags#3) num objects == 1
                  * 
                  *  Test Vectors:
                  *    limit: {-1}, {-231..-2, 0..232-1}
                  *    startDate: Addr_Set{null}, Inverse{null}
                  *    website: Addr_Set{null}, Inverse{null}
                  *    java.util.Iterator:hasNext(...)@1281: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@1297: {0}, {1}
                  */
  1245          Query query = null;
  1246          List queryResults = null;
  1247          
  1248          if (website != null) {
  1249              if (startDate != null) {
  1250                  Timestamp start = new Timestamp(startDate.getTime());
  1251                  query = strategy.getNamedQuery(
  1252                          "WeblogEntryTagAggregate.getPopularTagsByWebsite&StartDate");
  1253                  query.setParameter(1, website);
  1254                  query.setParameter(2, start);
  1255              } else {
  1256                  query = strategy.getNamedQuery(
  1257                          "WeblogEntryTagAggregate.getPopularTagsByWebsite");
  1258                  query.setParameter(1, website);
  1259              }
  1260          } else {
  1261              if (startDate != null) {
  1262                  Timestamp start = new Timestamp(startDate.getTime());
  1263                  query = strategy.getNamedQuery(
  1264                          "WeblogEntryTagAggregate.getPopularTagsByWebsiteNull&StartDate");
  1265                  query.setParameter(1, start);
  1266              } else {
  1267                  query = strategy.getNamedQuery(
  1268                          "WeblogEntryTagAggregate.getPopularTagsByWebsiteNull");
  1269              }
  1270          }
  1271          if (limit != -1) {
  1272              query.setMaxResults(limit);
  1273          }
  1274          queryResults = query.getResultList();
  1275          
  1276          double min = Integer.MAX_VALUE;
  1277          double max = Integer.MIN_VALUE;
  1278          
  1279          List results = new ArrayList(limit);
  1280          
  1281          for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
  1282              Object[] row = (Object[]) iter.next();
  1283              TagStat t = new TagStat();
  1284              t.setName((String) row[0]);
+ 1285              t.setCount(((Number) row[1]).intValue());
  1286              
  1287              min = Math.min(min, t.getCount());
  1288              max = Math.max(max, t.getCount());
  1289              results.add(t);
  1290          }
  1291          
  1292          min = Math.log(1+min);
  1293          max = Math.log(1+max);
  1294          
  1295          double range = Math.max(.01, max - min) * 1.0001;
  1296          
  1297          for (Iterator iter = results.iterator(); iter.hasNext(); ) {
  1298              TagStat t = (TagStat) iter.next();
  1299              t.setIntensity((int) (1 + Math.floor(5 * (Math.log(1+t.getCount()) - min) / range)));
  1300          }
  1301          
  1302          // sort results by name, because query had to sort by total
  1303          Collections.sort(results, tagStatNameComparator);
  1304          
  1305          return results;
  1306      }
  1307      
  1308      /**
  1309       * @inheritDoc
  1310       */
  1311      public List getTags(Weblog website, String sortBy,
  1312              String startsWith, int limit) throws WebloggerException {
                 /* 
    P/P           *  Method: List getTags(Weblog, String, String, int)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@1352 != null
                  *    javax.persistence.Query:getResultList(...)@1348 != null
                  *    row.length@1352 >= 2
                  * 
                  *  Postconditions:
                  *    return_value == &new ArrayList(getTags#6)
                  *    new ArrayList(getTags#6) num objects == 1
                  * 
                  *  Test Vectors:
                  *    limit: {-1}, {-231..-2, 0..232-1}
                  *    sortBy: Inverse{null}, Addr_Set{null}
                  *    startsWith: Addr_Set{null}, Inverse{null}
                  *    website: Addr_Set{null}, Inverse{null}
                  *    java.lang.String:equals(...)@1334: {0}, {1}
                  *    java.lang.String:length(...)@1329: {0}, {1..232-1}
                  *    java.util.Iterator:hasNext(...)@1351: {0}, {1}
                  */
  1313          Query query = null;
  1314          List queryResults = null;
  1315          boolean sortByName = sortBy == null || !sortBy.equals("count");
  1316                  
  1317          List params = new ArrayList();
  1318          int size = 0;
  1319          StringBuffer queryString = new StringBuffer();            
  1320          queryString.append("SELECT w.name, SUM(w.total) FROM WeblogEntryTagAggregate w WHERE ");
  1321                  
  1322          if (website != null) {
  1323              params.add(size++, website.getId());
  1324              queryString.append(" w.weblog.id = ?").append(size);
  1325          } else {
  1326              queryString.append(" w.weblog IS NULL"); 
  1327          }
  1328                         
  1329          if (startsWith != null && startsWith.length() > 0) {
  1330              params.add(size++, startsWith + '%');
  1331              queryString.append(" AND w.name LIKE ?" + size);
  1332          }
  1333                      
  1334          if (sortBy != null && sortBy.equals("count")) {
  1335              sortBy = "w.total DESC";
  1336          } else {
  1337              sortBy = "w.name";
  1338          }
  1339          queryString.append(" GROUP BY w.name, w.total ORDER BY " + sortBy);
  1340  
  1341          query = strategy.getDynamicQuery(queryString.toString());
  1342          for (int i=0; i<params.size(); i++) {
  1343              query.setParameter(i+1, params.get(i));
  1344          }
  1345          if (limit != -1) {
  1346              query.setMaxResults(limit);
  1347          }
  1348          queryResults = query.getResultList();
  1349          
  1350          List results = new ArrayList();
  1351          for (Iterator iter = queryResults.iterator(); iter.hasNext();) {
  1352              Object[] row = (Object[]) iter.next();
  1353              TagStat ce = new TagStat();
  1354              ce.setName((String) row[0]);
  1355              // The JPA query retrieves SUM(w.total) always as long
+ 1356              ce.setCount(((Long) row[1]).intValue());
  1357              results.add(ce);
  1358          }
  1359          
  1360          if (sortByName) {
  1361              Collections.sort(results, tagStatNameComparator);
  1362          } else {
  1363              Collections.sort(results, tagStatCountReverseComparator);
  1364          }
  1365          
  1366          return results;
  1367      }
  1368      
  1369      
  1370      /**
  1371       * @inheritDoc
  1372       */
  1373      public boolean getTagComboExists(List tags, Weblog weblog) throws WebloggerException{
  1374          
                 /* 
    P/P           *  Method: bool getTagComboExists(List, Weblog)
                  * 
                  *  Preconditions:
                  *    (soft) this.strategy != null
                  *    (soft) this.strategy.emf != null
                  *    (soft) this.strategy.threadLocalEntityManager != null
                  * 
                  *  Presumptions:
                  *    java.lang.String:length(...)@1394 - java.lang.StringBuffer:length(...)@1394 in -232+1..231
                  *    java.util.List:size(...)@1385 <= 232-2
                  *    java.util.List:size(...)@1388 <= 232-2
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    tags: Addr_Set{null}, Inverse{null}
                  *    weblog: Addr_Set{null}, Inverse{null}
                  *    java.util.List:size(...)@1375: {-231..-1, 1..232-1}, {0}
                  */
  1375          if(tags == null || tags.size() == 0) {
  1376              return false;
  1377          }
  1378          
  1379          StringBuffer queryString = new StringBuffer();
  1380          queryString.append("SELECT DISTINCT w.name ");
  1381          queryString.append("FROM WeblogEntryTagAggregate w WHERE w.name IN (");
  1382          //?1) AND w.weblog = ?2");
  1383          //Append tags as parameter markers to avoid potential escaping issues
  1384          //The IN clause would be of form (?1, ?2, ?3, ..)
  1385          ArrayList params = new ArrayList(tags.size() + 1);
+ 1386          final String PARAM_SEPERATOR = ", ";
  1387          int i;
  1388          for (i=0; i < tags.size(); i++) {
  1389              queryString.append('?').append(i+1).append(PARAM_SEPERATOR);
  1390              params.add(tags.get(i));
  1391          }
  1392          
  1393          // Remove the trailing PARAM_SEPERATOR
  1394          queryString.delete(queryString.length() - PARAM_SEPERATOR.length(),
  1395                  queryString.length());
  1396          // Close the brace of IN clause
  1397          queryString.append(')');
  1398          
  1399          if(weblog != null) {
  1400              queryString.append(" AND w.weblog = ?").append(i+1);
  1401              params.add(weblog);
  1402          } else {
  1403              queryString.append(" AND w.weblog IS NULL");
  1404          }
  1405          
  1406          Query q = strategy.getDynamicQuery(queryString.toString());
  1407          for (int j=0; j<params.size(); j++) {
  1408              q.setParameter(j+1, params.get(j));
  1409          }
  1410          List results = q.getResultList();
  1411          
  1412          //TODO: DatamapperPort: Since we are only interested in knowing whether
  1413          //results.size() == tags.size(). This query can be optimized to just fetch COUNT
  1414          //instead of objects as done currently
  1415          return (results != null && results.size() == tags.size());
  1416      }
  1417      
  1418      /**
  1419       * @inheritDoc
  1420       */
  1421      public void updateTagCount(String name, Weblog website, int amount)
  1422      throws WebloggerException {
                 /* 
    P/P           *  Method: void updateTagCount(String, Weblog, int)
                  * 
                  *  Preconditions:
                  *    amount != 0
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    website != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    amount + org.apache.roller.weblogger.pojos.WeblogEntryTagAggregate:getTotal(...)@1464 in -231..232-1
                  *    amount + org.apache.roller.weblogger.pojos.WeblogEntryTagAggregate:getTotal(...)@1484 in -231..232-1
                  *    javax.persistence.EntityManager:createNamedQuery(...)@301 != null
                  * 
                  *  Test Vectors:
                  *    amount: {-231..-1}, {1..232-1}
                  */
  1423          if(amount == 0) {
  1424              throw new WebloggerException("Tag increment amount cannot be zero.");
  1425          }
  1426          
  1427          if(website == null) {
  1428              throw new WebloggerException("Website cannot be NULL.");
  1429          }
  1430          
  1431          // The reason why add order lastUsed desc is to make sure we keep picking the most recent
  1432          // one in the case where we have multiple rows (clustered environment)
  1433          // eventually that second entry will have a very low total (most likely 1) and
  1434          // won't matter
  1435          Query weblogQuery = strategy.getNamedQuery(
  1436                  "WeblogEntryTagAggregate.getByName&WebsiteOrderByLastUsedDesc");
  1437          weblogQuery.setParameter(1, name);
  1438          weblogQuery.setParameter(2, website);
  1439          WeblogEntryTagAggregate weblogTagData;
  1440          try {
  1441              weblogTagData = (WeblogEntryTagAggregate)weblogQuery.getSingleResult();
  1442          } catch (NoResultException e) {
  1443              weblogTagData = null;
  1444          }
  1445          
  1446          Query siteQuery = strategy.getNamedQuery(
  1447                  "WeblogEntryTagAggregate.getByName&WebsiteNullOrderByLastUsedDesc");
  1448          siteQuery.setParameter(1, name);
  1449          WeblogEntryTagAggregate siteTagData;
  1450          try {
  1451              siteTagData = (WeblogEntryTagAggregate)siteQuery.getSingleResult();
  1452          } catch (NoResultException e) {
  1453              siteTagData = null;
  1454          }
  1455          Timestamp lastUsed = new Timestamp((new Date()).getTime());
  1456          
  1457          // create it only if we are going to need it.
  1458          if (weblogTagData == null && amount > 0) {
  1459              weblogTagData = new WeblogEntryTagAggregate(null, website, name, amount);
  1460              weblogTagData.setLastUsed(lastUsed);
  1461              strategy.store(weblogTagData);
  1462              
  1463          } else if (weblogTagData != null) {
  1464              weblogTagData.setTotal(weblogTagData.getTotal() + amount);
  1465              weblogTagData.setLastUsed(lastUsed);
  1466              strategy.store(weblogTagData);
  1467              // Why use update query when only one object needs update?
  1468  //            Query update = strategy.getNamedUpdate(
  1469  //                    "WeblogEntryTagAggregate.updateAddToTotalByName&Weblog");
  1470  //            update.setParameter(1, new Long(amount));
  1471  //            update.setParameter(2, lastUsed);
  1472  //            update.setParameter(3, weblogTagData.getName());
  1473  //            update.setParameter(4, website);
  1474  //            update.executeUpdate();
  1475          }
  1476          
  1477          // create it only if we are going to need it.
  1478          if (siteTagData == null && amount > 0) {
  1479              siteTagData = new WeblogEntryTagAggregate(null, null, name, amount);
  1480              siteTagData.setLastUsed(lastUsed);
  1481              strategy.store(siteTagData);
  1482              
  1483          } else if(siteTagData != null) {
  1484              siteTagData.setTotal(siteTagData.getTotal() + amount);
  1485              siteTagData.setLastUsed(lastUsed);
  1486              strategy.store(siteTagData);
  1487              // Why use update query when only one object needs update?
  1488  //            Query update = strategy.getNamedUpdate(
  1489  //                    "WeblogEntryTagAggregate.updateAddToTotalByName&WeblogNull");
  1490  //            update.setParameter(1, new Long(amount));
  1491  //            update.setParameter(2, siteTagData.getName());
  1492  //            update.executeUpdate();
  1493          }
  1494          
  1495          // delete all bad counts
  1496          Query removeq = strategy.getNamedUpdate(
  1497                  "WeblogEntryTagAggregate.removeByTotalLessEqual");
  1498          removeq.setParameter(1, new Integer(0));
  1499          removeq.executeUpdate();
  1500      }
  1501      
  1502      /**
  1503       * @inheritDoc
  1504       */
  1505      public WeblogHitCount getHitCount(String id) throws WebloggerException {
  1506          
  1507          // do lookup
                 /* 
    P/P           *  Method: WeblogHitCount getHitCount(String)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1508          return (WeblogHitCount) strategy.load(WeblogHitCount.class, id);
  1509      }
  1510      
  1511      /**
  1512       * @inheritDoc
  1513       */
  1514      public WeblogHitCount getHitCountByWeblog(Weblog weblog)
  1515      throws WebloggerException {
                 /* 
    P/P           *  Method: WeblogHitCount getHitCountByWeblog(Weblog)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1516          Query q = strategy.getNamedQuery("WeblogHitCount.getByWeblog");
  1517          q.setParameter(1, weblog);
  1518          try {
  1519              return (WeblogHitCount)q.getSingleResult();
  1520          } catch (NoResultException e) {
  1521              return null;
  1522          }
  1523      }
  1524      
  1525      /**
  1526       * @inheritDoc
  1527       */
  1528      public List getHotWeblogs(int sinceDays, int offset, int length)
  1529      throws WebloggerException {
  1530          
  1531          // figure out start date
                 /* 
    P/P           *  Method: List getHotWeblogs(int, int, int)
                  * 
                  *  Preconditions:
                  *    sinceDays <= 231
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.Calendar:getInstance(...)@1532 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  * 
                  *  Test Vectors:
                  *    length: {-1}, {-231..-2, 0..232-1}
                  *    offset: {0}, {-231..-1, 1..232-1}
                  */
  1532          Calendar cal = Calendar.getInstance();
  1533          cal.setTime(new Date());
  1534          cal.add(Calendar.DATE, -1 * sinceDays);
  1535          Date startDate = cal.getTime();
  1536          
  1537          Query query = strategy.getNamedQuery(
  1538                  "WeblogHitCount.getByWeblogEnabledTrueAndActiveTrue&DailyHitsGreaterThenZero&WeblogLastModifiedGreaterOrderByDailyHitsDesc");
  1539          query.setParameter(1, startDate);
  1540          
  1541          // Was commented out due to https://glassfish.dev.java.net/issues/show_bug.cgi?id=2084
  1542          // TODO: determine if this is still an issue. Is it a problem with other JPA implementations?
  1543          if (offset != 0) {
  1544              query.setFirstResult(offset);
  1545          }
  1546          if (length != -1) {
  1547              query.setMaxResults(length);
  1548          }        
  1549          return query.getResultList();
  1550      }
  1551      
  1552      
  1553      /**
  1554       * @inheritDoc
  1555       */
  1556      public void saveHitCount(WeblogHitCount hitCount) throws WebloggerException {
                 /* 
    P/P           *  Method: void saveHitCount(WeblogHitCount)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  */
  1557          this.strategy.store(hitCount);
  1558      }
  1559      
  1560      
  1561      /**
  1562       * @inheritDoc
  1563       */
  1564      public void removeHitCount(WeblogHitCount hitCount) throws WebloggerException {
                 /* 
    P/P           *  Method: void removeHitCount(WeblogHitCount)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  */
  1565          this.strategy.remove(hitCount);
  1566      }
  1567      
  1568      
  1569      /**
  1570       * @inheritDoc
  1571       */
  1572      public void incrementHitCount(Weblog weblog, int amount)
  1573      throws WebloggerException {
  1574          
                 /* 
    P/P           *  Method: void incrementHitCount(Weblog, int)
                  * 
                  *  Preconditions:
                  *    amount != 0
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    weblog != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    amount + org.apache.roller.weblogger.pojos.WeblogHitCount:getDailyHits(...)@1599 in -231..232-1
                  * 
                  *  Test Vectors:
                  *    amount: {-231..-1}, {1..232-1}
                  */
  1575          if(amount == 0) {
  1576              throw new WebloggerException("Tag increment amount cannot be zero.");
  1577          }
  1578          
  1579          if(weblog == null) {
  1580              throw new WebloggerException("Website cannot be NULL.");
  1581          }
  1582          
  1583          Query q = strategy.getNamedQuery("WeblogHitCount.getByWeblog");
  1584          q.setParameter(1, weblog);
  1585          WeblogHitCount hitCount = null;
  1586          try {
  1587              hitCount = (WeblogHitCount)q.getSingleResult();
  1588          } catch (NoResultException e) {
  1589              hitCount = null;
  1590          }
  1591          
  1592          // create it if it doesn't exist
  1593          if(hitCount == null && amount > 0) {
  1594              hitCount = new WeblogHitCount();
  1595              hitCount.setWeblog(weblog);
  1596              hitCount.setDailyHits(amount);
  1597              strategy.store(hitCount);
  1598          } else if(hitCount != null) {
  1599              hitCount.setDailyHits(hitCount.getDailyHits() + amount);
  1600              strategy.store(hitCount);
  1601          }
  1602      }
  1603      
  1604      /**
  1605       * @inheritDoc
  1606       */
  1607      public void resetAllHitCounts() throws WebloggerException {       
                 /* 
    P/P           *  Method: void resetAllHitCounts()
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    javax.persistence.EntityManager:createNamedQuery(...)@301 != null
                  */
  1608          Query q = strategy.getNamedUpdate("WeblogHitCount.updateDailyHitCountZero");
  1609          q.executeUpdate();
  1610      }
  1611      
  1612      /**
  1613       * @inheritDoc
  1614       */
  1615      public void resetHitCount(Weblog weblog) throws WebloggerException {
                 /* 
    P/P           *  Method: void resetHitCount(Weblog)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    javax.persistence.Query:getSingleResult(...)@1620 != null
                  */
  1616          Query q = strategy.getNamedQuery("WeblogHitCount.getByWeblog");
  1617          q.setParameter(1, weblog);
  1618          WeblogHitCount hitCount = null;
  1619          try {
  1620              hitCount = (WeblogHitCount)q.getSingleResult();
  1621              hitCount.setDailyHits(0);
  1622              strategy.store(hitCount);
  1623          } catch (NoResultException e) {
  1624              // ignore: no hit count for weblog
  1625          }       
  1626  
  1627      }
  1628      
  1629      /**
  1630       * @inheritDoc
  1631       */
  1632      public long getCommentCount() throws WebloggerException {
                 /* 
    P/P           *  Method: long getCommentCount()
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.List:get(...)@1637 != null
                  *    javax.persistence.Query:getResultList(...)@1636 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1633          Query q = strategy.getNamedQuery(
  1634                  "WeblogEntryComment.getCountAllDistinctByStatus");
  1635          q.setParameter(1, WeblogEntryComment.APPROVED);
  1636          List results = q.getResultList();
  1637          return ((Long)results.get(0)).longValue();
  1638      }
  1639      
  1640      /**
  1641       * @inheritDoc
  1642       */
  1643      public long getCommentCount(Weblog website) throws WebloggerException {
                 /* 
    P/P           *  Method: long getCommentCount(Weblog)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.List:get(...)@1649 != null
                  *    javax.persistence.Query:getResultList(...)@1648 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1644          Query q = strategy.getNamedQuery(
  1645                  "WeblogEntryComment.getCountDistinctByWebsite&Status");
  1646          q.setParameter(1, website);
  1647          q.setParameter(2, WeblogEntryComment.APPROVED);
  1648          List results = q.getResultList();
  1649          return ((Long)results.get(0)).longValue();
  1650      }
  1651      
  1652      /**
  1653       * @inheritDoc
  1654       */
  1655      public long getEntryCount() throws WebloggerException {
                 /* 
    P/P           *  Method: long getEntryCount()
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.List:get(...)@1660 != null
                  *    javax.persistence.Query:getResultList(...)@1659 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1656          Query q = strategy.getNamedQuery(
  1657                  "WeblogEntry.getCountDistinctByStatus");
  1658          q.setParameter(1, "PUBLISHED");
  1659          List results = q.getResultList();
  1660          return ((Long)results.get(0)).longValue();
  1661      }
  1662      
  1663      /**
  1664       * @inheritDoc
  1665       */
  1666      public long getEntryCount(Weblog website) throws WebloggerException {
                 /* 
    P/P           *  Method: long getEntryCount(Weblog)
                  * 
                  *  Preconditions:
                  *    this.strategy != null
                  *    this.strategy.threadLocalEntityManager != null
                  *    (soft) this.strategy.emf != null
                  * 
                  *  Presumptions:
                  *    java.util.List:get(...)@1672 != null
                  *    javax.persistence.Query:getResultList(...)@1671 != null
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
  1667          Query q = strategy.getNamedQuery(
  1668                  "WeblogEntry.getCountDistinctByStatus&Website");
  1669          q.setParameter(1, "PUBLISHED");
  1670          q.setParameter(2, website);
  1671          List results = q.getResultList();
  1672          return ((Long)results.get(0)).longValue();
  1673      }
  1674      
  1675      /**
  1676       * Appends given expression to given whereClause. If whereClause already
  1677       * has other conditions, an " AND " is also appended before appending
  1678       * the expression
  1679       * @param whereClause The given where Clauuse
  1680       * @param expression The given expression
  1681       * @return the whereClause.
  1682       */
  1683      private static StringBuffer appendConjuctionToWhereclause(StringBuffer whereClause,
  1684              String expression) {
                 /* 
    P/P           *  Method: StringBuffer appendConjuctionToWhereclause(StringBuffer, String)
                  * 
                  *  Preconditions:
                  *    whereClause != null
                  *    (soft) expression != null
                  * 
                  *  Postconditions:
                  *    return_value == whereClause
                  *    return_value != null
                  *    whereClause._tainted == old whereClause._tainted | One-of{expression._tainted, old whereClause._tainted}
                  *    init'ed(whereClause._tainted)
                  * 
                  *  Test Vectors:
                  *    java.lang.String:length(...)@1685: {0}, {1..232-1}
                  *    java.lang.StringBuffer:length(...)@1685: {0}, {-231..-1, 1..232-1}
                  */
  1685          if(whereClause.length() != 0 && expression.length() != 0) {
  1686              whereClause.append(" AND ");
  1687          }
  1688          return whereClause.append(expression);
  1689      }
  1690      
  1691  }








SofCheck Inspector Build Version : 2.18479
JPAWeblogManagerImpl.java 2009-Jan-02 14:25:16
JPAWeblogManagerImpl.class 2009-Sep-04 03:12:31