blogservice.java

### File Source: blogservice.java

         1  /*
         2   * Copyright (c) 2003-2006, Simon Brown
         3   * All rights reserved.
         4   *
         5   * Redistribution and use in source and binary forms, with or without
         6   * modification, are permitted provided that the following conditions are met:
         7   *
         8   *   - Redistributions of source code must retain the above copyright
         9   *     notice, this list of conditions and the following disclaimer.
        10   *
        11   *   - Redistributions in binary form must reproduce the above copyright
        12   *     notice, this list of conditions and the following disclaimer in
        13   *     the documentation and/or other materials provided with the
        14   *     distribution.
        15   *
        16   *   - Neither the name of Pebble nor the names of its contributors may
        17   *     be used to endorse or promote products derived from this software
        18   *     without specific prior written permission.
        19   *
        20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
        24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        30   * POSSIBILITY OF SUCH DAMAGE.
        31   */
        32  package net.sourceforge.pebble.domain;
        33
        34  import net.sourceforge.pebble.api.event.blogentry.BlogEntryEvent;
        35  import net.sourceforge.pebble.api.event.comment.CommentEvent;
        36  import net.sourceforge.pebble.api.event.trackback.TrackBackEvent;
        37  import net.sourceforge.pebble.dao.BlogEntryDAO;
        38  import net.sourceforge.pebble.dao.DAOFactory;
        39  import net.sourceforge.pebble.dao.PersistenceException;
        40  import net.sourceforge.pebble.ContentCache;
        41  import org.apache.commons.logging.Log;
        42  import org.apache.commons.logging.LogFactory;
        43
        44  import java.util.ArrayList;
        45  import java.util.Date;
        46  import java.util.List;
        47  import java.util.Collection;
        48
        49  /**
        50   * Service that encompasses all functionality related to getting, putting
        51   * and removing blog entries.
        52   *
        53   * @author    Simon Brown
        54   */
             /*
        P/P   *  Method: void net.sourceforge.pebble.domain.BlogService()
              */
        55  public class BlogService {
        56
               /*
        P/P     *  Method: net.sourceforge.pebble.domain.BlogService__static_init
                *
                *  Postconditions:
                *    init'ed(log)
                */
        57    private static final Log log = LogFactory.getLog(BlogService.class);
        58
        59    /**
        60     * Gets the blog entry with the specified id.
        61     *
        62     * @param blogEntryId   the id of the blog entry
        63     * @return  a BlogEntry instance, or null if the entry couldn't be found
        64     */
        65    public BlogEntry getBlogEntry(Blog blog, String blogEntryId) throws BlogServiceException {
                 /*
        P/P       *  Method: BlogEntry getBlogEntry(Blog, String)
                  *
                  *  Preconditions:
                  *    blog != null
                  *    (soft) net/sourceforge/pebble/dao/file/FileBlogEntryDAO.log != null
                  *
                  *  Presumptions:
                  *    org.apache.commons.logging.LogFactory:getLog(...)@57 != null
                  *
                  *  Postconditions:
                  *    new BlogEntry(loadBlogEntry#2*) num objects <= 1
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).attachment)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).date)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).eventsEnabled)
                  *    possibly_updated(new BlogEntry(loadBlogEntry#2*).id)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).lockedBy)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).originalPermalink)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).permalink)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).persistent)
                  *    init'ed(new BlogEntry(loadBlogEntry#2*).timeZoneId)
                  *
                  *  Preconditions:
                  *    init'ed(blog.id)
                  *    net.sourceforge.pebble.ContentCache__static_init.new ContentCache(ContentCache__static_init#1).cache != null
                  *    (soft) net.sourceforge.pebble.domain.State__static_init.new State(State__static_init#4).name != null
                  *    (soft) net.sourceforge.pebble.domain.State__static_init.new State(State__static_init#5).name != null
                  *    (soft) net/sourceforge/pebble/dao/DAOFactory.configuredFactory != null
                  *    (soft) net/sourceforge/pebble/dao/DAOFactory.configuredFactory.blogEntryDAO != null
                  *
                  *  Presumptions:
                  *    blogEntry.blog@77 != null
                  *    blogEntry.categories@70 != null
                  *    blogEntry.categories@77 != null
                  *    blogEntry.categories@81 != null
                  *    blogEntry.comments@70 != null
                  *    ...
                  *
                  *  Postconditions:
                  *    return_value in Addr_Set{null,&new BlogEntry(clone#1)}
                  *    new ArrayList(BlogEntry#2) num objects == One-of{0, 1, new ArrayList(BlogEntry#2) num objects + 1}
                  *    new ArrayList(BlogEntry#2) num objects <= 2
                  *    new ArrayList(BlogEntry#3) num objects == One-of{0, 1, new ArrayList(BlogEntry#3) num objects + 1}
                  *    new ArrayList(BlogEntry#3) num objects <= 2
                  *    init'ed(new ArrayList(Content#1) num objects)
                  *    init'ed(new ArrayList(Content#3) num objects)
                  *    new ArrayList(parse#1) num objects <= 1
                  *    new Attachment(clone#1*) num objects <= 1
                  *    init'ed(new Attachment(clone#1*).size)
                  *    ...
                  */
        66      BlogEntry blogEntry = null;
        67      ContentCache cache = ContentCache.getInstance();
        68
        69      // is the blog entry already in the cache?
        70      blogEntry = cache.getBlogEntry(blog, blogEntryId);
        71      if (blogEntry != null) {
        72        log.debug("Got blog entry " + blogEntryId + " from cache");
        73      } else {
        74        log.debug("Loading blog entry " + blogEntryId + " from disk");
        75        BlogEntryDAO dao = DAOFactory.getConfiguredFactory().getBlogEntryDAO();
        76        try {
        77          blogEntry = dao.loadBlogEntry(blog, blogEntryId);
        78
        79          if (blogEntry != null) {
        80            // place in the cache for faster lookup next time
        81            cache.putBlogEntry(blogEntry);
        82          }
        83        } catch (PersistenceException pe) {
        84          throw new BlogServiceException(blog, pe);
        85        }
        86      }
        87
        88      if (blogEntry != null) {
        89        blogEntry = (BlogEntry)blogEntry.clone();
        90        blogEntry.setEventsEnabled(true);
        91        blogEntry.setPersistent(true);
        92      }
        93
        94      return blogEntry;
        95    }
        96
        97    public List<BlogEntry> getBlogEntries(Blog blog, int year, int month, int day) throws BlogServiceException {
                 /*
        P/P       *  Method: List getBlogEntries(Blog, int, int, int)
                  *
                  *  Preconditions:
                  *    blog != null
                  *
                  *  Postconditions:
                  *    return_value == &new ArrayList(getBlogEntries#1*)
                  *    new ArrayList(getBlogEntries#1*) num objects == 1
                  *
                  *  Preconditions:
                  *    blog.years != null
                  *    day >= 1
                  *    month in 1..12
                  */
        98      Day d = blog.getBlogForDay(year, month, day);
    +   99      List<String> blogEntryIds = d.getBlogEntries();
       100      return getBlogEntries(blog, blogEntryIds);
       101    }
       102
       103    public List<BlogEntry> getBlogEntries(Blog blog, int year, int month) throws BlogServiceException {
                 /*
        P/P       *  Method: List getBlogEntries(Blog, int, int)
                  *
                  *  Preconditions:
                  *    blog != null
                  *
                  *  Postconditions:
                  *    return_value == &new ArrayList(getBlogEntries#1*)
                  *    new ArrayList(getBlogEntries#1*) num objects == 1
                  *
                  *  Preconditions:
                  *    blog.years != null
                  *    month in 1..12
                  *
                  *  Presumptions:
                  *    m.dailyBlogs.length@104 <= 232-1
                  *    m.dailyBlogs@104 != null
                  */
       104      Month m = blog.getBlogForMonth(year, month);
    +  105      List<String> blogEntryIds = m.getBlogEntries();
       106      return getBlogEntries(blog, blogEntryIds);
       107    }
       108
       109    /**
       110     * Gets all blog entries for the specified blog.
       111     *
       112     * @return  a List of BlogEntry objects
       113     */
       114    public Collection<BlogEntry> getBlogEntries(Blog blog) throws BlogServiceException {
                 /*
        P/P       *  Method: Collection getBlogEntries(Blog)
                  *
                  *  Preconditions:
                  *    blog != null
                  *    net/sourceforge/pebble/dao/DAOFactory.configuredFactory != null
                  *    net/sourceforge/pebble/dao/DAOFactory.configuredFactory.blogEntryDAO != null
                  *    (soft) net/sourceforge/pebble/dao/file/FileBlogEntryDAO.log != null
                  *
                  *  Presumptions:
                  *    java.util.Iterator:next(...)@119 != null
                  *
                  *  Postconditions:
                  *    new ArrayList(loadBlogEntries#1) num objects == 1
                  *
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@119: {1}, {0}
                  *
                  *  Postconditions:
                  *    (soft) return_value == &new ArrayList(loadBlogEntries#1)
                  */
       115      BlogEntryDAO dao = DAOFactory.getConfiguredFactory().getBlogEntryDAO();
       116      Collection<BlogEntry> blogEntries;
       117      try {
       118        blogEntries = dao.loadBlogEntries(blog);
       119        for (BlogEntry blogEntry : blogEntries) {
       120          blogEntry.setPersistent(true);
       121        }
       122
       123      } catch (PersistenceException pe) {
       124        throw new BlogServiceException(blog, pe);
       125      }
       126
       127      return blogEntries;
       128    }
       129
       130    private List<BlogEntry> getBlogEntries(Blog blog, List<String> blogEntryIds) throws BlogServiceException {
                 /*
        P/P       *  Method: List getBlogEntries(Blog, List)
                  *
                  *  Preconditions:
                  *    blogEntryIds != null
                  *
                  *  Postconditions:
                  *    return_value == &new ArrayList(getBlogEntries#1)
                  *    new ArrayList(getBlogEntries#1) num objects == 1
                  *
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@133: {1}, {0}
                  */
       131      List<BlogEntry> blogEntries = new ArrayList<BlogEntry>();
       132
       133      for (String blogEntryId : blogEntryIds) {
       134        BlogEntry blogEntry = getBlogEntry(blog, blogEntryId);
       135        blogEntries.add(blogEntry);
       136      }
       137
       138      return blogEntries;
       139    }
       140
       141    /**
       142     * Puts the blog entry with the specified id.
       143     */
       144    public void putBlogEntry(BlogEntry blogEntry) throws BlogServiceException {
                 /*
        P/P       *  Method: void putBlogEntry(BlogEntry)
                  *
                  *  Preconditions:
                  *    blogEntry != null
                  *    blogEntry.blog != null
                  *    net/sourceforge/pebble/dao/DAOFactory.configuredFactory != null
                  *    init'ed(blogEntry.id)
                  *    init'ed(blogEntry.persistent)
                  *    (soft) init'ed(blogEntry.attachment)
                  *    (soft) init'ed(blogEntry.attachment.size)
                  *    (soft) init'ed(blogEntry.attachment.type)
                  *    (soft) init'ed(blogEntry.attachment.url)
                  *    (soft) init'ed(blogEntry.categories)
                  *    ...
                  *
                  *  Presumptions:
                  *    blogEntry.comments@158 != null
                  *    java.util.Date:getTime(...)@157 <= 264-2
                  *    net/sourceforge/pebble/dao/file/FileBlogEntryDAO.log@152 != null
                  *
                  *  Postconditions:
                  *    init'ed(blogEntry.date)
                  *    blogEntry.events != null
                  *    blogEntry.eventsEnabled == 1
                  *    init'ed(blogEntry.id)
                  *    possibly_updated(blogEntry.permalink)
                  *    blogEntry.persistent == 1
                  *    blogEntry.propertyChangeEvents == &new ArrayList(clearPropertyChangeEvents#1)
                  *    new ArrayList(clearEvents#1*) num objects >= 1
                  *    new ArrayList(clearPropertyChangeEvents#1) num objects == 1
                  *    new Date(putBlogEntry#1) num objects <= 1
                  *
                  *  Preconditions:
                  *    blogEntry.comments != null
                  *    init'ed(blogEntry.trackBacks)
                  *    (soft) init'ed(blogEntry.author)
                  *    (soft) init'ed(blogEntry.body)
                  *    (soft) init'ed(blogEntry.originalPermalink)
                  *    (soft) blogEntry.state != null
                  *    (soft) init'ed(blogEntry.state.name)
                  *    (soft) init'ed(blogEntry.subtitle)
                  *    (soft) init'ed(blogEntry.tags)
                  *    (soft) init'ed(blogEntry.title)
                  *    ...
                  *
                  *  Presumptions:
                  *    getBlog(...).eventDispatcher@152 != null
                  *    getEventDispatcher(...).eventListenerList.blogEntryListeners@152 != null
                  *    getEventDispatcher(...).eventListenerList.commentListeners@152 != null
                  *    getEventDispatcher(...).eventListenerList.trackBackListeners@152 != null
                  *    getEventDispatcher(...).eventListenerList@152 != null
                  *
                  *  Test Vectors:
                  *    blogEntry.persistent: {1}, {0}
                  *    getBlogEntry(...)@152: Addr_Set{null}, Inverse{null}
                  *    java.util.Iterator:hasNext(...)@164: {1}, {0}
                  */
       145      DAOFactory factory = DAOFactory.getConfiguredFactory();
       146      BlogEntryDAO dao = factory.getBlogEntryDAO();
       147      Blog blog = blogEntry.getBlog();
       148      ContentCache cache = ContentCache.getInstance();
       149
       150      synchronized (blog) {
       151        try {
       152          BlogEntry be = getBlogEntry(blog, blogEntry.getId());
       153
       154          if (!blogEntry.isPersistent() && be != null) {
       155            // the blog entry is new but one exists with the same ID already
       156            // - increment the date/ID and try again
       157            blogEntry.setDate(new Date(blogEntry.getDate().getTime() + 1));
       158            putBlogEntry(blogEntry);
       159          } else {
       160            if (!blogEntry.isPersistent()) {
       161              dao.storeBlogEntry(blogEntry);
       162              blogEntry.insertEvent(new BlogEntryEvent(blogEntry, BlogEntryEvent.BLOG_ENTRY_ADDED));
       163
       164              for (Comment comment : blogEntry.getComments()) {
       165                blogEntry.addEvent(new CommentEvent(comment, CommentEvent.COMMENT_ADDED));
       166              }
       167              for (TrackBack trackBack : blogEntry.getTrackBacks()) {
       168                blogEntry.addEvent(new TrackBackEvent(trackBack, TrackBackEvent.TRACKBACK_ADDED));
       169              }
       170            } else {
       171              dao.storeBlogEntry(blogEntry);
       172              if (blogEntry.isDirty()) {
       173                blogEntry.insertEvent(new BlogEntryEvent(blogEntry, blogEntry.getPropertyChangeEvents()));
       174              }
       175            }
       176
       177            blogEntry.getBlog().getEventDispatcher().fireEvents(blogEntry);
       178
       179            // and store the blog entry now that listeners have been fired
       180            dao.storeBlogEntry(blogEntry);
       181            cache.removeBlogEntry(blogEntry);
       182          }
       183
       184          blogEntry.setPersistent(true);
       185        } catch (PersistenceException pe) {
       186          throw new BlogServiceException(blog, pe);
       187        } finally {
       188          blogEntry.clearPropertyChangeEvents();
       189          blogEntry.clearEvents();
       190          blogEntry.setEventsEnabled(true);
       191        }
       192      }
       193    }
       194
       195    /**
       196     * Removes this blog entry.
       197     */
       198    public void removeBlogEntry(BlogEntry blogEntry) throws BlogServiceException {
                 /*
        P/P       *  Method: void removeBlogEntry(BlogEntry)
                  *
                  *  Preconditions:
                  *    blogEntry != null
                  *    blogEntry.blog != null
                  *    blogEntry.comments != null
                  *    blogEntry.events != null
                  *    init'ed(blogEntry.id)
                  *    init'ed(blogEntry.trackBacks)
                  *    net/sourceforge/pebble/dao/DAOFactory.configuredFactory != null
                  *    net/sourceforge/pebble/dao/DAOFactory.configuredFactory.blogEntryDAO != null
                  *    net/sourceforge/pebble/dao/file/FileBlogEntryDAO.log != null
                  *
                  *  Postconditions:
                  *    blogEntry.persistent == 0
                  *
                  *  Preconditions:
                  *    blogEntry.blog.eventDispatcher != null
                  *    init'ed(blogEntry.blog.id)
                  *    net.sourceforge.pebble.ContentCache__static_init.new ContentCache(ContentCache__static_init#1).cache != null
                  *    (soft) blogEntry.blog.eventDispatcher.eventListenerList != null
                  *    (soft) blogEntry.blog.eventDispatcher.eventListenerList.blogEntryListeners != null
                  *    (soft) blogEntry.blog.eventDispatcher.eventListenerList.commentListeners != null
                  *    (soft) blogEntry.blog.eventDispatcher.eventListenerList.trackBackListeners != null
                  *
                  *  Test Vectors:
                  *    java.util.Iterator:hasNext(...)@215: {1}, {0}
                  *    java.util.Iterator:hasNext(...)@218: {1}, {0}
                  */
       199      Blog blog = blogEntry.getBlog();
       200      ContentCache cache = ContentCache.getInstance();
       201
       202      try {
       203        DAOFactory factory = DAOFactory.getConfiguredFactory();
       204        BlogEntryDAO dao = factory.getBlogEntryDAO();
       205        dao.removeBlogEntry(blogEntry);
       206        blogEntry.setPersistent(false);
       207
       208        // remove from cache
       209        cache.removeBlogEntry(blogEntry);
       210
       211        blogEntry.insertEvent(new BlogEntryEvent(blogEntry, BlogEntryEvent.BLOG_ENTRY_REMOVED));
       212
       213        // and remove all of the responses, so the appropriate events are raised
       214        // and the responses get unindexed
       215        for (Comment comment : blogEntry.getComments()) {
       216          blogEntry.addEvent(new CommentEvent(comment, CommentEvent.COMMENT_REMOVED));
       217        }
       218        for (TrackBack trackBack : blogEntry.getTrackBacks()) {
       219          blogEntry.addEvent(new TrackBackEvent(trackBack, TrackBackEvent.TRACKBACK_REMOVED));
       220        }
       221
       222        blogEntry.getBlog().getEventDispatcher().fireEvents(blogEntry);
       223      } catch (PersistenceException pe) {
       224        throw new BlogServiceException(blogEntry.getBlog(), pe);
       225      }
       226    }
       227
       228    /**
       229     * Gets the blog entry with the specified id.
       230     *
       231     * @param responseId    the id of the response
       232     * @return  a response instance, or null if the entry couldn't be found
       233     */
       234    public Response getResponse(Blog blog, String responseId) throws BlogServiceException {
                 /*
        P/P       *  Method: Response getResponse(Blog, String)
                  *
                  *  Preconditions:
                  *    responseId != null
                  *
                  *  Presumptions:
                  *    blogEntry.comments@236 != null
                  *    java.lang.String:indexOf(...)@235 <= 232-2
                  *
                  *  Postconditions:
                  *    init'ed(return_value)
                  *
                  *  Test Vectors:
                  *    getBlogEntry(...)@236: Addr_Set{null}, Inverse{null}
                  */
       235      String blogEntryId = responseId.substring(responseId.indexOf("/")+1, responseId.lastIndexOf("/"));
       236      BlogEntry blogEntry = getBlogEntry(blog, blogEntryId);
       237      if (blogEntry != null) {
       238        return blogEntry.getResponse(responseId);
       239      } else {
       240        return null;
       241      }
       242    }
       243
       244  }

SofCheck Inspector Build Version : 2.22510

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