relatedpostsdecorator.java

### File Source: relatedpostsdecorator.java

         1  package net.sourceforge.pebble.decorator;
         2
         3  import java.util.HashSet;
         4  import java.util.List;
         5  import java.util.Set;
         6
         7  import net.sourceforge.pebble.PluginProperties;
         8  import net.sourceforge.pebble.api.decorator.ContentDecoratorContext;
         9  import net.sourceforge.pebble.domain.Blog;
        10  import net.sourceforge.pebble.domain.BlogEntry;
        11  import net.sourceforge.pebble.domain.Tag;
        12  import net.sourceforge.pebble.util.I18n;
        13  import net.sourceforge.pebble.util.StringUtils;
        14
        15  import org.apache.commons.logging.Log;
        16  import org.apache.commons.logging.LogFactory;
        17
        18  /**
        19   * Adds related posts to the current post. The posts are selected by matching
        20   * tags of the current post to the tags of other posts in the blog. One related
        21   * post per tag.
        22   *
        23   * Each blog entry can have up to six related posts or none.
        24   *
        25   * @author Alexander Zagniotov
        26   */
             /*
        P/P   *  Method: void net.sourceforge.pebble.decorator.RelatedPostsDecorator()
              */
        27  public class RelatedPostsDecorator extends ContentDecoratorSupport {
        28
               /*
        P/P     *  Method: net.sourceforge.pebble.decorator.RelatedPostsDecorator__static_init
                *
                *  Postconditions:
                *    init'ed(log)
                */
        29    private static final Log log = LogFactory.getLog(RelatedPostsDecorator.class);
        30
        31    /** the name of the max number of posts property */
        32    public static final String MAX_POSTS = "RelatedPostsDecorator.maxPosts";
        33
        34    /**
        35     * Decorates the specified blog entry.
        36     *
        37     * @param context
        38     *          the context in which the decoration is running
        39     * @param blogEntry
        40     *          the blog entry to be decorated
        41     */
        42    public void decorate(ContentDecoratorContext context, BlogEntry blogEntry) {
        43
                 /*
        P/P       *  Method: void decorate(ContentDecoratorContext, BlogEntry)
                  *
                  *  Preconditions:
                  *    blogEntry != null
                  *
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@77 != null
                  *    java.util.Iterator:next(...)@85 != null
                  *    org.apache.commons.logging.LogFactory:getLog(...)@29 != null
                  *
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@80: {0}, {1}
                  *    java.lang.String:length(...)@60: {0}, {1..232-1}
                  *    java.util.Iterator:hasNext(...)@77: {1}, {0}
                  *    java.util.Iterator:hasNext(...)@85: {1}, {0}
                  *    java.util.Set:add(...)@90: {0}, {1}
                  *    java.util.Set:size(...)@103: {-231..-1, 1..232-1}, {0}
                  *
                  *  Preconditions:
                  *    blogEntry.blog != null
                  *    init'ed(blogEntry.body)
                  *    (soft) init'ed(blogEntry.categories)
                  *    (soft) blogEntry.propertyChangeSupport != null
                  *    (soft) blogEntry.tagsAsList != null
                  *    (soft) init'ed(blogEntry.title)
                  *
                  *  Presumptions:
                  *    entry.blog@77 != null
                  *    entry.blog@90 != null
                  *    entry.tagsAsList@77 != null
                  *    entry.title@77 != null
                  *
                  *  Postconditions:
                  *    init'ed(blogEntry.body)
                  *
                  *  Preconditions:
                  *    blogEntry.blog.pluginProperties != null
                  *    (soft) blogEntry.blog.rootCategory != null
                  *    (soft) init'ed(blogEntry.blog.rootCategory...parent)
                  *    (soft) init'ed(blogEntry.blog.rootCategory...tagsAsList)
                  *    (soft) init'ed(blogEntry.blog.rootCategory.parent)
                  *    (soft) init'ed(blogEntry.blog.rootCategory.tagsAsList)
                  *    (soft) blogEntry.blog.years != null
                  *    (soft) net/sourceforge/pebble/domain/BlogManager.instance != null
                  *    (soft) init'ed(net/sourceforge/pebble/domain/BlogManager.instance.multiBlog)
                  *
                  *  Presumptions:
                  *    entry.blog.rootCategory@77 != null
                  *
                  *  Test Vectors:
                  *    blogEntry.body: Addr_Set{null}, Inverse{null}
                  *    net.sourceforge.pebble.PluginProperties:hasProperty(...)@47: {0}, {1}
                  */
        44      PluginProperties props = blogEntry.getBlog().getPluginProperties();
        45      int maxPosts = StringUtils.MAX_NUM_OF_POSTS;
        46
        47      if (props.hasProperty(RelatedPostsDecorator.MAX_POSTS)) {
        48        try {
        49          maxPosts = Integer.parseInt(props.getProperty(MAX_POSTS));
        50        }
        51        catch (NumberFormatException nfe) {
        52          log.error(nfe.getMessage());
        53          // do nothing, the value has already been defaulted
        54        }
        55      }
        56
        57      Blog blog = blogEntry.getBlog();
        58      String body = blogEntry.getBody();
        59
        60      if (body != null && body.trim().length() > 0) {
        61
        62        StringBuffer buf = new StringBuffer();
        63        buf.append(body);
        64        buf.append("<p><b>" + I18n.getMessage(blog, "common.relatedPosts") + "</b><br />");
        65
        66        // tags of the current entry
        67        List<Tag> currentEntryTags = blogEntry.getAllTags();
        68
        69        // all blog entries of the current blog
        70        List<BlogEntry> allBlogEntries = (List<BlogEntry>) blog.getBlogEntries();
        71
        72        // temporary holder for accumulated unique related posts.
        73        // using hash set assures that we wont have same related post twice for
        74        // different tags.
        75        Set<BlogEntry> relatedEntries = new HashSet<BlogEntry>();
        76
        77        for (BlogEntry entry : allBlogEntries) {
        78
        79          // don't add current entry as a related post of it self, skip it
        80          if (entry.getTitle().equals(blogEntry.getTitle()))
        81            continue;
        82
        83          // loop through each of the current entry tags, and try to find related
        84          // post by matching current tag to the posts tags
        85          for (Tag currentTag : currentEntryTags) {
        86            if (entry.hasTag(currentTag.getName())) {
        87              // if we successfully selected related post - create hyperlink for
        88              // it
        89              // TODO: Missing escaping -- XSS vulnerabilities here :(
        90              if (relatedEntries.add(entry))
        91                buf.append("<a href=\"" + entry.getPermalink() + "\" rel=\"bookmark\" title=\"" + entry.getTitle()
        92                    + "\">" + entry.getTitle() + "</a><br />");
        93            }
        94          }
        95
        96          // do not allow more than default amount of posts or
        97          // amount set through the RelatedPostsDecorator.maxPosts property
        98          if (relatedEntries.size() == maxPosts) {
        99            break;
       100          }
       101        }
       102
       103        if (relatedEntries.size() == 0)
       104          buf.append("<i>" + I18n.getMessage(blog, "common.noRelatedPosts") + "</i>");
       105
       106        buf.append("</p><br />");
       107        blogEntry.setBody(buf.toString());
       108      }
       109    }
       110  }

SofCheck Inspector Build Version : 2.22510

relatedpostsdecorator.java | 2010-Jun-25 19:40:32
relatedpostsdecorator.class | 2010-Jul-19 20:23:40