pebbleapiblogentryaggregator.java

### File Source: pebbleapiblogentryaggregator.java

             /*
        P/P   *  Method: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init
              *
              *  Postconditions:
              *    init'ed(log)
              */
         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.event.blog;
        33
        34  import net.sourceforge.pebble.domain.*;
        35  import net.sourceforge.pebble.webservice.PebbleAPIHandler;
        36  import net.sourceforge.pebble.PluginProperties;
        37  import net.sourceforge.pebble.api.event.blog.BlogEvent;
        38  import net.sourceforge.pebble.api.event.blog.BlogListener;
        39  import org.apache.commons.logging.Log;
        40  import org.apache.commons.logging.LogFactory;
             /*
        P/P   *  Method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()
              *
              *  Postconditions:
              *    this.timer == &new Timer(PebbleAPIBlogEntryAggregator#1)
              *    new Timer(PebbleAPIBlogEntryAggregator#1) num objects == 1
              */
        41  import org.apache.xmlrpc.XmlRpcClient;
        42
        43  import java.util.*;
        44
        45  /**
        46   * Blog listener that polls a Pebble blog, using the Pebble XML-RPC API,
        47   * to pull across and aggregate blog entries. This assumes that the IDs of
        48   * blog entries in both the local and remote blogs don't clash.
        49   *
        50   * @author Simon Brown
        51   */
        52  public abstract class PebbleAPIBlogEntryAggregator extends TimerTask implements BlogListener {
        53
        54    private static final int ONE_HOUR = 1000 * 60 * 60;
        55    private static final Log log = LogFactory.getLog(PebbleAPIBlogEntryAggregator.class);
        56
        57    public static final String XMLRPC_URL_KEY = ".xmlrpcUrl";
        58    public static final String BLOG_KEY = ".blog";
        59    public static final String USERNAME_KEY = ".username";
        60    public static final String PASSWORD_KEY = ".password";
        61    public static final String BLOG_ENTRIES_KEY = ".blogEntries";
        62
        63    private Blog blog;
        64    private Timer timer = new Timer();
        65
        66    /**
        67     * Called when a blog has been started.
        68     *
        69     * @param event   a BlogEvent instance
        70     */
               /*
        P/P     *  Method: void blogStarted(BlogEvent)
                *
                *  Preconditions:
                *    event != null
                *    this.timer != null
                *
                *  Postconditions:
                *    init'ed(this.blog)
                */
        71    public void blogStarted(BlogEvent event) {
        72      this.blog = event.getBlog();
        73      timer.schedule(this, 0, ONE_HOUR);
        74    }
        75
        76    /**
        77     * Called when a blog has been stopped.
        78     *
        79     * @param event   a BlogEvent instance
        80     */
               /*
        P/P     *  Method: void blogStopped(BlogEvent)
                *
                *  Preconditions:
                *    this.timer != null
                */
        81    public void blogStopped(BlogEvent event) {
        82      timer.cancel();
        83    }
        84
        85    /**
        86     *
        87     */
        88    public void run() {
        89      try {
        90        PluginProperties props = blog.getPluginProperties();
                   /*
        P/P         *  Method: void run()
                    *
                    *  Preconditions:
                    *    (soft) this.blog != null
                    *    (soft) this.blog.pluginProperties != null
                    *
                    *  Presumptions:
                    *    blogEntry.categories@129 != null
                    *    blogEntry.categories@134 != null
                    *    blogEntry.propertyChangeSupport@129 != null
                    *    blogEntry.propertyChangeSupport@134 != null
                    *    java.util.Hashtable:get(...)@169 != null
                    *    ...
                    *
                    *  Postconditions:
                    *    init'ed(new ArrayList(Category#1) num objects)
                    *    init'ed(new ArrayList(Category#2) num objects)
                    *    init'ed(new ArrayList(Category#3) num objects)
                    *    init'ed(new Category(getCategory#2*) num objects)
                    *    init'ed(new Category(getCategory#2*).blog)
                    *    init'ed(new Category(getCategory#2*).blogEntries)
                    *    init'ed(new Category(getCategory#2*).id)
                    *    init'ed(new Category(getCategory#2*).name)
                    *    init'ed(new Category(getCategory#2*).parent)
                    *    init'ed(new Category(getCategory#2*).subCategories)
                    *    ...
                    *
                    *  Test Vectors:
                    *    getBlogEntry(...)@129: Inverse{null}, Addr_Set{null}
                    *    java.util.Hashtable:get(...)@118: Addr_Set{null}, Inverse{null}
                    *    java.util.Hashtable:get(...)@119: Addr_Set{null}, Inverse{null}
                    *    java.util.Hashtable:get(...)@120: Addr_Set{null}, Inverse{null}
                    *    java.util.Iterator:hasNext(...)@148: {1}, {0}
                    *    java.util.Iterator:hasNext(...)@156: {1}, {0}
                    *    java.util.Iterator:hasNext(...)@159: {0}, {1}
                    *    preAggregate(...)@122: {1}, {0}
                    */
        91        XmlRpcClient xmlrpc = new XmlRpcClient(props.getProperty(getPropertyPrefix() + XMLRPC_URL_KEY));
        92        Vector<Object> params = new Vector<Object>();
        93        params.add(props.getProperty(getPropertyPrefix() + BLOG_KEY));
        94        params.add(props.getProperty(getPropertyPrefix() + USERNAME_KEY));
        95        params.add(props.getProperty(getPropertyPrefix() + PASSWORD_KEY));
        96
        97        int numberOfBlogEntries = 10;
        98        try {
        99          numberOfBlogEntries = Integer.parseInt(props.getProperty(getPropertyPrefix() + BLOG_ENTRIES_KEY));
       100        } catch (NumberFormatException nfe) {
       101          // do nothing, the value has already been defaulted
       102        }
       103        params.add(numberOfBlogEntries);
       104
       105        // get the remote blog entries
       106        Vector<Hashtable> remoteBlogEntries = (Vector<Hashtable>)xmlrpc.execute("pebble.getRecentBlogEntries", params);
       107
       108        // loop through them and add them to the local blog
       109        for (Hashtable remoteBlogEntry : remoteBlogEntries) {
       110          String id = (String)remoteBlogEntry.get(PebbleAPIHandler.ID);
       111          String title = (String)remoteBlogEntry.get(PebbleAPIHandler.TITLE);
       112          String subtitle = (String)remoteBlogEntry.get(PebbleAPIHandler.SUBTITLE);
       113          String excerpt = (String)remoteBlogEntry.get(PebbleAPIHandler.EXCERPT);
       114          String body = (String)remoteBlogEntry.get(PebbleAPIHandler.BODY);
    +  115          Date date = (Date)remoteBlogEntry.get(PebbleAPIHandler.DATE);
       116          String author = (String)remoteBlogEntry.get(PebbleAPIHandler.AUTHOR);
       117          String permalink = (String)remoteBlogEntry.get(PebbleAPIHandler.PERMALINK);
       118          Vector<String> categories = (Vector<String>)remoteBlogEntry.get(PebbleAPIHandler.CATEGORIES);
       119          Vector<String> tags = (Vector<String>)remoteBlogEntry.get(PebbleAPIHandler.TAGS);
       120          Hashtable attachment = (Hashtable)remoteBlogEntry.get(PebbleAPIHandler.ATTACHMENT);
       121
       122          if (!preAggregate(remoteBlogEntry)) {
       123            continue;
       124          }
       125
       126          log.info("Aggregating " + title + " [ " + id + " | " + permalink + " ]");
       127
       128          BlogService service = new BlogService();
       129          BlogEntry blogEntry = service.getBlogEntry(blog, id);
       130          if (blogEntry == null) {
       131            // create a new blog entry if one doesn't exist
       132            blogEntry = new BlogEntry(blog);
       133            blogEntry.setDate(new Date(Long.parseLong(id)));
       134            service.putBlogEntry(blogEntry);
       135          }
       136
       137          // now ensure the local blog entry is in sync
       138          blogEntry.setTitle(title);
       139          blogEntry.setSubtitle(subtitle);
       140          blogEntry.setBody(body);
       141          blogEntry.setExcerpt(excerpt);
       142          blogEntry.setAuthor(author);
       143          blogEntry.setOriginalPermalink(permalink);
       144          blogEntry.setCommentsEnabled(false);
       145          blogEntry.setTrackBacksEnabled(false);
       146
       147          if (categories != null) {
       148            for (String categoryId : categories) {
       149              blogEntry.addCategory(blog.getCategory(categoryId));
       150            }
       151          }
       152
       153          if (tags != null) {
       154            StringBuffer buf = new StringBuffer();
       155            Iterator it = tags.iterator();
       156            while (it.hasNext()) {
       157              String tag = (String)it.next();
       158              buf.append(tag);
       159              if (it.hasNext()) {
       160                buf.append(" ");
       161              }
       162            }
       163            blogEntry.setTags(buf.toString());
       164          }
       165
       166          if (attachment != null) {
       167            Attachment a = new Attachment();
       168            a.setUrl((String)attachment.get(PebbleAPIHandler.ATTACHMENT_URL));
       169            a.setSize((Long)attachment.get(PebbleAPIHandler.ATTACHMENT_SIZE));
       170            a.setType((String)attachment.get(PebbleAPIHandler.ATTACHMENT_TYPE));
       171            blogEntry.setAttachment(a);
       172          }
       173
       174          postAggregate(blogEntry);
       175
       176          service.putBlogEntry(blogEntry);
       177        }
       178      } catch (Exception e) {
       179        log.error("Exception encountered", e);
       180      }
       181    }
       182
       183    /**
       184     * Called before each blog entry is aggregated. Returning false will
       185     * stop the entry from being aggregated.
       186     *
       187     * @param blogEntry   a Hashtable instance representing a blog entry
       188     * @return  true if the blog entry should be aggregated, false otherwise
       189     */
       190    protected abstract boolean preAggregate(Hashtable blogEntry);
       191
       192    /**
       193     * Called after each blog entry is aggregated. Use this to enrich
       194     * aggregated blog entries.
       195     *
       196     * @param blogEntry   a Hashtable instance representing a blog entry
       197     */
       198    protected abstract void postAggregate(BlogEntry blogEntry);
       199
       200    /**
       201     * Gets the prefix to use when defining properties for this plugin.
       202     *
       203     * @return  a String (the class name)
       204     */
               /*
        P/P     *  Method: String getPropertyPrefix()
                *
                *  Presumptions:
                *    java.lang.Object:getClass(...)@206 != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       205    protected String getPropertyPrefix() {
       206      return this.getClass().getSimpleName();
       207    }
       208
       209  }

SofCheck Inspector Build Version : 2.22510

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