//# 0 errors, 305 messages
//#
/*
    //#pebbleapiblogentryaggregator.java:1:1: class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
 * Copyright (c) 2003-2006, Simon Brown
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   - Neither the name of Pebble nor the names of its contributors may
 *     be used to endorse or promote products derived from this software
 *     without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package net.sourceforge.pebble.event.blog;

import net.sourceforge.pebble.domain.*;
import net.sourceforge.pebble.webservice.PebbleAPIHandler;
import net.sourceforge.pebble.PluginProperties;
import net.sourceforge.pebble.api.event.blog.BlogEvent;
import net.sourceforge.pebble.api.event.blog.BlogListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xmlrpc.XmlRpcClient;

import java.util.*;

/**
 * Blog listener that polls a Pebble blog, using the Pebble XML-RPC API,
 * to pull across and aggregate blog entries. This assumes that the IDs of
 * blog entries in both the local and remote blogs don't clash. 
 *
 * @author Simon Brown
 */
public abstract class PebbleAPIBlogEntryAggregator extends TimerTask implements BlogListener {
    //#pebbleapiblogentryaggregator.java:52: method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()
    //#input(void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()): this
    //#output(void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()): new Timer(PebbleAPIBlogEntryAggregator#1) num objects
    //#output(void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()): this.timer
    //#new obj(void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()): new Timer(PebbleAPIBlogEntryAggregator#1)
    //#post(void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()): this.timer == &new Timer(PebbleAPIBlogEntryAggregator#1)
    //#post(void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()): new Timer(PebbleAPIBlogEntryAggregator#1) num objects == 1

  private static final int ONE_HOUR = 1000 * 60 * 60;
  private static final Log log = LogFactory.getLog(PebbleAPIBlogEntryAggregator.class);
    //#pebbleapiblogentryaggregator.java:55: method: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init
    //#pebbleapiblogentryaggregator.java:55: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Descendant_Table[net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator]
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.blogStarted(Lnet/sourceforge/pebble/api/event/blog/BlogEvent;)V
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.blogStopped(Lnet/sourceforge/pebble/api/event/blog/BlogEvent;)V
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.getPropertyPrefix()Ljava/lang/String;
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.postAggregate(Lnet/sourceforge/pebble/domain/BlogEntry;)V
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.preAggregate(Ljava/util/Hashtable;)Z
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.run()V
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): log
    //#output(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): net/sourceforge/pebble/api/event/blog/BlogListener.__Descendant_Table[net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator]
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Descendant_Table[net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): net/sourceforge/pebble/api/event/blog/BlogListener.__Descendant_Table[net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.blogStarted(Lnet/sourceforge/pebble/api/event/blog/BlogEvent;)V == &blogStarted
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.blogStopped(Lnet/sourceforge/pebble/api/event/blog/BlogEvent;)V == &blogStopped
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.getPropertyPrefix()Ljava/lang/String; == &getPropertyPrefix
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.postAggregate(Lnet/sourceforge/pebble/domain/BlogEntry;)V == &postAggregate
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.preAggregate(Ljava/util/Hashtable;)Z == &preAggregate
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): __Dispatch_Table.run()V == &run
    //#post(net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init): init'ed(log)
    //#pebbleapiblogentryaggregator.java:55: end of method: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator__static_init

  public static final String XMLRPC_URL_KEY = ".xmlrpcUrl";
  public static final String BLOG_KEY = ".blog";
  public static final String USERNAME_KEY = ".username";
  public static final String PASSWORD_KEY = ".password";
  public static final String BLOG_ENTRIES_KEY = ".blogEntries";

  private Blog blog;
  private Timer timer = new Timer();
    //#pebbleapiblogentryaggregator.java:64: end of method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator()

  /**
   * Called when a blog has been started.
   *
   * @param event   a BlogEvent instance
   */
  public void blogStarted(BlogEvent event) {
    this.blog = event.getBlog();
    //#pebbleapiblogentryaggregator.java:72: method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.blogStarted(BlogEvent)
    //#input(void blogStarted(BlogEvent)): event
    //#input(void blogStarted(BlogEvent)): event.__Tag
    //#input(void blogStarted(BlogEvent)): net/sourceforge/pebble/api/event/blog/BlogEvent.__Descendant_Table[net/sourceforge/pebble/api/event/blog/BlogEvent]
    //#input(void blogStarted(BlogEvent)): net/sourceforge/pebble/api/event/blog/BlogEvent.__Descendant_Table[others]
    //#input(void blogStarted(BlogEvent)): net/sourceforge/pebble/api/event/blog/BlogEvent.__Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(void blogStarted(BlogEvent)): net/sourceforge/pebble/domain/Blog.__Descendant_Table[net/sourceforge/pebble/domain/Blog]
    //#input(void blogStarted(BlogEvent)): net/sourceforge/pebble/domain/Blog.__Descendant_Table[others]
    //#input(void blogStarted(BlogEvent)): this
    //#input(void blogStarted(BlogEvent)): this.timer
    //#output(void blogStarted(BlogEvent)): this.blog
    //#pre[1] (void blogStarted(BlogEvent)): event != null
    //#pre[2] (void blogStarted(BlogEvent)): event.__Tag == net/sourceforge/pebble/api/event/blog/BlogEvent
    //#pre[4] (void blogStarted(BlogEvent)): this.timer != null
    //#post(void blogStarted(BlogEvent)): init'ed(this.blog)
    //#unanalyzed(void blogStarted(BlogEvent)): Effects-of-calling:net.sourceforge.pebble.api.event.blog.BlogEvent:getSource
    timer.schedule(this, 0, ONE_HOUR);
  }
    //#pebbleapiblogentryaggregator.java:74: end of method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.blogStarted(BlogEvent)

  /**
   * Called when a blog has been stopped.
   *
   * @param event   a BlogEvent instance
   */
  public void blogStopped(BlogEvent event) {
    timer.cancel();
    //#pebbleapiblogentryaggregator.java:82: method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.blogStopped(BlogEvent)
    //#input(void blogStopped(BlogEvent)): this
    //#input(void blogStopped(BlogEvent)): this.timer
    //#pre[2] (void blogStopped(BlogEvent)): this.timer != null
  }
    //#pebbleapiblogentryaggregator.java:83: end of method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.blogStopped(BlogEvent)

  /**
   *
   */
  public void run() {
    try {
      PluginProperties props = blog.getPluginProperties();
    //#pebbleapiblogentryaggregator.java:90: method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.run()
    //#input(void run()): __Descendant_Table[net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator]
    //#input(void run()): __Descendant_Table[others]
    //#input(void run()): __Dispatch_Table.getPropertyPrefix()Ljava/lang/String;
    //#input(void run()): __Dispatch_Table.postAggregate(Lnet/sourceforge/pebble/domain/BlogEntry;)V
    //#input(void run()): __Dispatch_Table.preAggregate(Ljava/util/Hashtable;)Z
    //#input(void run()): log
    //#input(void run()): net.sourceforge.pebble.domain.State__static_init.new State(State__static_init#4).__Tag
    //#input(void run()): net.sourceforge.pebble.domain.State__static_init.new State(State__static_init#5).__Tag
    //#input(void run()): net/sourceforge/pebble/domain/Attachment.__Descendant_Table[net/sourceforge/pebble/domain/Attachment]
    //#input(void run()): net/sourceforge/pebble/domain/Attachment.__Dispatch_Table.setSize(J)V
    //#input(void run()): net/sourceforge/pebble/domain/Attachment.__Dispatch_Table.setType(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/Attachment.__Dispatch_Table.setUrl(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/Blog.__Descendant_Table[net/sourceforge/pebble/domain/Blog]
    //#input(void run()): net/sourceforge/pebble/domain/Blog.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/Blog.__Dispatch_Table.getCategory(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/Category;
    //#input(void run()): net/sourceforge/pebble/domain/Blog.__Dispatch_Table.getPluginProperties()Lnet/sourceforge/pebble/PluginProperties;
    //#input(void run()): net/sourceforge/pebble/domain/Blog.__Dispatch_Table.getRootCategory()Lnet/sourceforge/pebble/domain/Category;
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Descendant_Table[net/sourceforge/pebble/domain/BlogEntry]
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.addCategory(Lnet/sourceforge/pebble/domain/Category;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.addEvent(Lnet/sourceforge/pebble/api/event/PebbleEvent;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.areEventsEnabled()Z
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getAllTags()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getCategories()Ljava/util/Set;
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getState()Lnet/sourceforge/pebble/domain/State;
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getTagsAsList()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.isPublished()Z
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.isUnpublished()Z
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setAttachment(Lnet/sourceforge/pebble/domain/Attachment;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setAuthor(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setBody(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setCommentsEnabled(Z)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setDate(Ljava/util/Date;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setExcerpt(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setOriginalPermalink(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setPublished(Z)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setState(Lnet/sourceforge/pebble/domain/State;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setSubtitle(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setTags(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setTitle(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setTrackBacksEnabled(Z)V
    //#input(void run()): net/sourceforge/pebble/domain/BlogService.__Descendant_Table[net/sourceforge/pebble/domain/BlogService]
    //#input(void run()): net/sourceforge/pebble/domain/BlogService.__Dispatch_Table.getBlogEntry(Lnet/sourceforge/pebble/domain/Blog;Ljava/lang/String;)Lnet/sourceforge/pebble/domain/BlogEntry;
    //#input(void run()): net/sourceforge/pebble/domain/BlogService.__Dispatch_Table.putBlogEntry(Lnet/sourceforge/pebble/domain/BlogEntry;)V
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Descendant_Table[net/sourceforge/pebble/domain/Category]
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.addSubCategory(Lnet/sourceforge/pebble/domain/Category;)V
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.getAllTags()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.getId()Ljava/lang/String;
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.getParent()Lnet/sourceforge/pebble/domain/Category;
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.getSubCategories()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.getTagsAsList()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.isRootCategory()Z
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.setId(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/domain/Category.__Dispatch_Table.setParent(Lnet/sourceforge/pebble/domain/Category;)V
    //#input(void run()): net/sourceforge/pebble/domain/CategoryBuilder.__Descendant_Table[net/sourceforge/pebble/domain/CategoryBuilder]
    //#input(void run()): net/sourceforge/pebble/domain/CategoryBuilder.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/CategoryBuilder.__Dispatch_Table.addCategory(Lnet/sourceforge/pebble/domain/Category;)V
    //#input(void run()): net/sourceforge/pebble/domain/CategoryBuilder.__Dispatch_Table.getCategory(Ljava/lang/String;)Lnet/sourceforge/pebble/domain/Category;
    //#input(void run()): net/sourceforge/pebble/domain/CategoryBuilder.__Dispatch_Table.getRootCategory()Lnet/sourceforge/pebble/domain/Category;
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Descendant_Table[net/sourceforge/pebble/domain/BlogEntry]
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Descendant_Table[net/sourceforge/pebble/domain/PageBasedContent]
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Descendant_Table[net/sourceforge/pebble/domain/StaticPage]
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Dispatch_Table.getAllTags()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Dispatch_Table.getState()Lnet/sourceforge/pebble/domain/State;
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Dispatch_Table.setDate(Ljava/util/Date;)V
    //#input(void run()): net/sourceforge/pebble/domain/PageBasedContent.__Dispatch_Table.setState(Lnet/sourceforge/pebble/domain/State;)V
    //#input(void run()): net/sourceforge/pebble/domain/State.PUBLISHED
    //#input(void run()): net/sourceforge/pebble/domain/State.UNPUBLISHED
    //#input(void run()): net/sourceforge/pebble/domain/State.__Descendant_Table[net/sourceforge/pebble/domain/State]
    //#input(void run()): net/sourceforge/pebble/domain/State.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/State.__Dispatch_Table.equals(Ljava/lang/Object;)Z
    //#input(void run()): net/sourceforge/pebble/domain/State.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Descendant_Table[net/sourceforge/pebble/domain/StaticPage]
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.getAllTags()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.getState()Lnet/sourceforge/pebble/domain/State;
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.getTagsAsList()Ljava/util/List;
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.setDate(Ljava/util/Date;)V
    //#input(void run()): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.setState(Lnet/sourceforge/pebble/domain/State;)V
    //#input(void run()): net/sourceforge/pebble/domain/Tag.__Descendant_Table[net/sourceforge/pebble/domain/Tag]
    //#input(void run()): net/sourceforge/pebble/domain/Tag.__Descendant_Table[net/sourceforge/pebble/index/IndexedTag]
    //#input(void run()): net/sourceforge/pebble/domain/Tag.__Descendant_Table[others]
    //#input(void run()): net/sourceforge/pebble/domain/Tag.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void run()): net/sourceforge/pebble/domain/Tag.__Dispatch_Table.setName(Ljava/lang/String;)V
    //#input(void run()): net/sourceforge/pebble/index/IndexedTag.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void run()): net/sourceforge/pebble/index/IndexedTag.__Dispatch_Table.setName(Ljava/lang/String;)V
    //#input(void run()): this
    //#input(void run()): this.__Tag
    //#input(void run()): this.blog
    //#input(void run()): this.blog.__Tag
    //#input(void run()): this.blog.pluginProperties
    //#output(void run()): new ArrayList(Category#1) num objects
    //#output(void run()): new ArrayList(Category#2) num objects
    //#output(void run()): new ArrayList(Category#3) num objects
    //#output(void run()): new Category(getCategory#2*) num objects
    //#output(void run()): new Category(getCategory#2*).__Tag
    //#output(void run()): new Category(getCategory#2*).blog
    //#output(void run()): new Category(getCategory#2*).blogEntries
    //#output(void run()): new Category(getCategory#2*).id
    //#output(void run()): new Category(getCategory#2*).name
    //#output(void run()): new Category(getCategory#2*).parent
    //#output(void run()): new Category(getCategory#2*).subCategories
    //#output(void run()): new Category(getCategory#2*).tags
    //#output(void run()): new Category(getCategory#2*).tagsAsList
    //#output(void run()): new Category(getCategory#3*) num objects
    //#output(void run()): new Category(getCategory#3*).__Tag
    //#output(void run()): new Category(getCategory#3*).blog
    //#output(void run()): new Category(getCategory#3*).blogEntries
    //#output(void run()): new Category(getCategory#3*).id
    //#output(void run()): new Category(getCategory#3*).name
    //#output(void run()): new Category(getCategory#3*).parent
    //#output(void run()): new Category(getCategory#3*).subCategories
    //#output(void run()): new Category(getCategory#3*).tags
    //#output(void run()): new Category(getCategory#3*).tagsAsList
    //#new obj(void run()): new ArrayList(Category#1)
    //#new obj(void run()): new ArrayList(Category#2)
    //#new obj(void run()): new ArrayList(Category#3)
    //#new obj(void run()): new Category(getCategory#2*)
    //#new obj(void run()): new Category(getCategory#3*)
    //#pre[5] (void run()): (soft) this.__Tag == net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator
    //#pre[6] (void run()): (soft) this.blog != null
    //#pre[7] (void run()): (soft) this.blog.__Tag == net/sourceforge/pebble/domain/Blog
    //#pre[8] (void run()): (soft) this.blog.pluginProperties != null
    //#presumption(void run()): blogEntry.__Tag@129 == net/sourceforge/pebble/domain/BlogEntry
    //#presumption(void run()): blogEntry.__Tag@134 == net/sourceforge/pebble/domain/BlogEntry
    //#presumption(void run()): blogEntry.categories@129 != null
    //#presumption(void run()): blogEntry.categories@134 != null
    //#presumption(void run()): blogEntry.propertyChangeSupport@129 != null
    //#presumption(void run()): blogEntry.propertyChangeSupport@134 != null
    //#presumption(void run()): java.util.Hashtable:get(...)@169 != null
    //#presumption(void run()): java.util.Iterator:next(...)@109 != null
    //#presumption(void run()): org.apache.commons.logging.LogFactory:getLog(...)@55 != null
    //#presumption(void run()): org.apache.xmlrpc.XmlRpcClient:execute(...)@106 != null
    //#presumption(void run()): this.__Tag@134 == net/sourceforge/pebble/event/blog/PebbleAPIBlogEntryAggregator
    //#presumption(void run()): this.blog.__Tag@134 == net/sourceforge/pebble/domain/Blog
    //#presumption(void run()): this.blog.__Tag@176 == net/sourceforge/pebble/domain/Blog
    //#presumption(void run()): this.blog@129 != null
    //#presumption(void run()): this.blog@134 != null
    //#post(void run()): init'ed(new ArrayList(Category#1) num objects)
    //#post(void run()): init'ed(new ArrayList(Category#2) num objects)
    //#post(void run()): init'ed(new ArrayList(Category#3) num objects)
    //#post(void run()): init'ed(new Category(getCategory#2*) num objects)
    //#post(void run()): init'ed(new Category(getCategory#2*).__Tag)
    //#post(void run()): init'ed(new Category(getCategory#2*).blog)
    //#post(void run()): init'ed(new Category(getCategory#2*).blogEntries)
    //#post(void run()): init'ed(new Category(getCategory#2*).id)
    //#post(void run()): init'ed(new Category(getCategory#2*).name)
    //#post(void run()): init'ed(new Category(getCategory#2*).parent)
    //#post(void run()): init'ed(new Category(getCategory#2*).subCategories)
    //#post(void run()): init'ed(new Category(getCategory#2*).tags)
    //#post(void run()): init'ed(new Category(getCategory#2*).tagsAsList)
    //#post(void run()): init'ed(new Category(getCategory#3*) num objects)
    //#post(void run()): init'ed(new Category(getCategory#3*).__Tag)
    //#post(void run()): init'ed(new Category(getCategory#3*).blog)
    //#post(void run()): init'ed(new Category(getCategory#3*).blogEntries)
    //#post(void run()): init'ed(new Category(getCategory#3*).id)
    //#post(void run()): init'ed(new Category(getCategory#3*).name)
    //#post(void run()): init'ed(new Category(getCategory#3*).parent)
    //#post(void run()): init'ed(new Category(getCategory#3*).subCategories)
    //#post(void run()): init'ed(new Category(getCategory#3*).tags)
    //#post(void run()): init'ed(new Category(getCategory#3*).tagsAsList)
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Object:getClass
    //#unanalyzed(void run()): Effects-of-calling:java.lang.Class:getSimpleName
    //#unanalyzed(void run()): Effects-of-calling:java.beans.PropertyChangeSupport:firePropertyChange
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void run()): Effects-of-calling:java.util.Date:getTime
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void run()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void run()): Effects-of-calling:java.util.HashSet
    //#unanalyzed(void run()): Effects-of-calling:setState
    //#unanalyzed(void run()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void run()): Effects-of-calling:java.beans.PropertyChangeSupport
    //#unanalyzed(void run()): Effects-of-calling:java.beans.PropertyChangeSupport:addPropertyChangeListener
    //#unanalyzed(void run()): Effects-of-calling:java.util.LinkedList
    //#unanalyzed(void run()): Effects-of-calling:java.util.Date
    //#unanalyzed(void run()): Effects-of-calling:setDate
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void run()): Effects-of-calling:net.sourceforge.pebble.util.StringUtils:transformHTML
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void run()): Effects-of-calling:getSubCategories
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void run()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void run()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void run()): Effects-of-calling:getCategory
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:equals
    //#unanalyzed(void run()): Effects-of-calling:net.sourceforge.pebble.domain.Blog:getLocale
    //#unanalyzed(void run()): Effects-of-calling:net.sourceforge.pebble.util.I18n:getMessage
    //#unanalyzed(void run()): Effects-of-calling:net.sourceforge.pebble.domain.Category
    //#unanalyzed(void run()): Effects-of-calling:addCategory
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void run()): Effects-of-calling:getId
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:lastIndexOf
    //#unanalyzed(void run()): Effects-of-calling:setBlog
    //#unanalyzed(void run()): Effects-of-calling:isRootCategory
    //#unanalyzed(void run()): Effects-of-calling:addSubCategory
    //#unanalyzed(void run()): Effects-of-calling:java.util.Set:contains
    //#unanalyzed(void run()): Effects-of-calling:java.util.Set:add
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:replaceAll
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:toLowerCase
    //#unanalyzed(void run()): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:contains
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:add
    //#unanalyzed(void run()): Effects-of-calling:getAllTags
    //#unanalyzed(void run()): Effects-of-calling:getTagsAsList
    //#unanalyzed(void run()): Effects-of-calling:java.util.Collections:sort
    //#unanalyzed(void run()): Effects-of-calling:net.sourceforge.pebble.api.event.PebbleEvent
    //#unanalyzed(void run()): Effects-of-calling:java.util.Collections:unmodifiableList
    //#unanalyzed(void run()): Effects-of-calling:java.util.Set:iterator
    //#unanalyzed(void run()): Effects-of-calling:java.util.Set:size
    //#unanalyzed(void run()): Effects-of-calling:java.util.List:addAll
    //#unanalyzed(void run()): Effects-of-calling:java.util.Collections:reverse
    //#unanalyzed(void run()): Effects-of-calling:getRootCategory
    //#unanalyzed(void run()): Effects-of-calling:java.util.EventObject
    //#test_vector(void run()): getBlogEntry(...)@129: Inverse{null}, Addr_Set{null}
    //#test_vector(void run()): java.util.Hashtable:get(...)@118: Addr_Set{null}, Inverse{null}
    //#test_vector(void run()): java.util.Hashtable:get(...)@119: Addr_Set{null}, Inverse{null}
    //#test_vector(void run()): java.util.Hashtable:get(...)@120: Addr_Set{null}, Inverse{null}
    //#test_vector(void run()): java.util.Iterator:hasNext(...)@148: {1}, {0}
    //#test_vector(void run()): java.util.Iterator:hasNext(...)@156: {1}, {0}
    //#test_vector(void run()): java.util.Iterator:hasNext(...)@159: {0}, {1}
    //#test_vector(void run()): preAggregate(...)@122: {1}, {0}
      XmlRpcClient xmlrpc = new XmlRpcClient(props.getProperty(getPropertyPrefix() + XMLRPC_URL_KEY));
    //#pebbleapiblogentryaggregator.java:91: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.PluginProperties:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: String net.sourceforge.pebble.PluginProperties:getProperty(String)
    //#pebbleapiblogentryaggregator.java:91: Warning: method not available
    //#    -- call on void org.apache.xmlrpc.XmlRpcClient(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: void org.apache.xmlrpc.XmlRpcClient(String)
      Vector<Object> params = new Vector<Object>();
      params.add(props.getProperty(getPropertyPrefix() + BLOG_KEY));
    //#pebbleapiblogentryaggregator.java:93: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.PluginProperties:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: String net.sourceforge.pebble.PluginProperties:getProperty(String)
      params.add(props.getProperty(getPropertyPrefix() + USERNAME_KEY));
    //#pebbleapiblogentryaggregator.java:94: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.PluginProperties:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: String net.sourceforge.pebble.PluginProperties:getProperty(String)
      params.add(props.getProperty(getPropertyPrefix() + PASSWORD_KEY));
    //#pebbleapiblogentryaggregator.java:95: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.PluginProperties:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: String net.sourceforge.pebble.PluginProperties:getProperty(String)

      int numberOfBlogEntries = 10;
      try {
        numberOfBlogEntries = Integer.parseInt(props.getProperty(getPropertyPrefix() + BLOG_ENTRIES_KEY));
    //#pebbleapiblogentryaggregator.java:99: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.PluginProperties:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: String net.sourceforge.pebble.PluginProperties:getProperty(String)
      } catch (NumberFormatException nfe) {
        // do nothing, the value has already been defaulted
      }
      params.add(numberOfBlogEntries);

      // get the remote blog entries
      Vector<Hashtable> remoteBlogEntries = (Vector<Hashtable>)xmlrpc.execute("pebble.getRecentBlogEntries", params);
    //#pebbleapiblogentryaggregator.java:106: Warning: method not available
    //#    -- call on Object org.apache.xmlrpc.XmlRpcClient:execute(String, Vector)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: Object org.apache.xmlrpc.XmlRpcClient:execute(String, Vector)

      // loop through them and add them to the local blog
      for (Hashtable remoteBlogEntry : remoteBlogEntries) {
        String id = (String)remoteBlogEntry.get(PebbleAPIHandler.ID);
        String title = (String)remoteBlogEntry.get(PebbleAPIHandler.TITLE);
        String subtitle = (String)remoteBlogEntry.get(PebbleAPIHandler.SUBTITLE);
        String excerpt = (String)remoteBlogEntry.get(PebbleAPIHandler.EXCERPT);
        String body = (String)remoteBlogEntry.get(PebbleAPIHandler.BODY);
        Date date = (Date)remoteBlogEntry.get(PebbleAPIHandler.DATE);
    //#pebbleapiblogentryaggregator.java:115: Warning: unused assignment
    //#    unused assignment into date
    //#    severity: LOW
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
        String author = (String)remoteBlogEntry.get(PebbleAPIHandler.AUTHOR);
        String permalink = (String)remoteBlogEntry.get(PebbleAPIHandler.PERMALINK);
        Vector<String> categories = (Vector<String>)remoteBlogEntry.get(PebbleAPIHandler.CATEGORIES);
        Vector<String> tags = (Vector<String>)remoteBlogEntry.get(PebbleAPIHandler.TAGS);
        Hashtable attachment = (Hashtable)remoteBlogEntry.get(PebbleAPIHandler.ATTACHMENT);

        if (!preAggregate(remoteBlogEntry)) {
    //#pebbleapiblogentryaggregator.java:122: Warning: method not available
    //#    -- call on bool preAggregate(Hashtable)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: bool preAggregate(Hashtable)
          continue;
        }

        log.info("Aggregating " + title + " [ " + id + " | " + permalink + " ]");
    //#pebbleapiblogentryaggregator.java:126: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)

        BlogService service = new BlogService();
        BlogEntry blogEntry = service.getBlogEntry(blog, id);
    //#pebbleapiblogentryaggregator.java:129: Warning: call too complex - analysis skipped
    //#    -- call on BlogEntry getBlogEntry(Blog, String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: BlogEntry getBlogEntry(Blog, String)
        if (blogEntry == null) {
          // create a new blog entry if one doesn't exist
          blogEntry = new BlogEntry(blog);
          blogEntry.setDate(new Date(Long.parseLong(id)));
          service.putBlogEntry(blogEntry);
    //#pebbleapiblogentryaggregator.java:134: Warning: call too complex - analysis skipped
    //#    -- call on void putBlogEntry(BlogEntry)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: void putBlogEntry(BlogEntry)
        }

        // now ensure the local blog entry is in sync
        blogEntry.setTitle(title);
        blogEntry.setSubtitle(subtitle);
        blogEntry.setBody(body);
        blogEntry.setExcerpt(excerpt);
        blogEntry.setAuthor(author);
        blogEntry.setOriginalPermalink(permalink);
        blogEntry.setCommentsEnabled(false);
        blogEntry.setTrackBacksEnabled(false);

        if (categories != null) {
          for (String categoryId : categories) {
            blogEntry.addCategory(blog.getCategory(categoryId));
          }
        }

        if (tags != null) {
          StringBuffer buf = new StringBuffer();
          Iterator it = tags.iterator();
          while (it.hasNext()) {
            String tag = (String)it.next();
            buf.append(tag);
            if (it.hasNext()) {
              buf.append(" ");
            }
          }
          blogEntry.setTags(buf.toString());
        }

        if (attachment != null) {
          Attachment a = new Attachment();
          a.setUrl((String)attachment.get(PebbleAPIHandler.ATTACHMENT_URL));
          a.setSize((Long)attachment.get(PebbleAPIHandler.ATTACHMENT_SIZE));
          a.setType((String)attachment.get(PebbleAPIHandler.ATTACHMENT_TYPE));
          blogEntry.setAttachment(a);
        }

        postAggregate(blogEntry);
    //#pebbleapiblogentryaggregator.java:174: Warning: method not available
    //#    -- call on void postAggregate(BlogEntry)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: void postAggregate(BlogEntry)

        service.putBlogEntry(blogEntry);
    //#pebbleapiblogentryaggregator.java:176: Warning: call too complex - analysis skipped
    //#    -- call on void putBlogEntry(BlogEntry)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: void putBlogEntry(BlogEntry)
      }
    } catch (Exception e) {
      log.error("Exception encountered", e);
    //#pebbleapiblogentryaggregator.java:179: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object, Throwable)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
    //#    method: void run()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object, Throwable)
    }
  }
    //#pebbleapiblogentryaggregator.java:181: end of method: void net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.run()

  /**
   * Called before each blog entry is aggregated. Returning false will
   * stop the entry from being aggregated.
   *
   * @param blogEntry   a Hashtable instance representing a blog entry
   * @return  true if the blog entry should be aggregated, false otherwise
   */
  protected abstract boolean preAggregate(Hashtable blogEntry);

  /**
   * Called after each blog entry is aggregated. Use this to enrich
   * aggregated blog entries.
   *
   * @param blogEntry   a Hashtable instance representing a blog entry
   */
  protected abstract void postAggregate(BlogEntry blogEntry);

  /**
   * Gets the prefix to use when defining properties for this plugin.
   *
   * @return  a String (the class name)
   */
  protected String getPropertyPrefix() {
    return this.getClass().getSimpleName();
    //#pebbleapiblogentryaggregator.java:206: method: String net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.getPropertyPrefix()
    //#input(String getPropertyPrefix()): this
    //#output(String getPropertyPrefix()): return_value
    //#presumption(String getPropertyPrefix()): java.lang.Object:getClass(...)@206 != null
    //#post(String getPropertyPrefix()): init'ed(return_value)
    //#pebbleapiblogentryaggregator.java:206: end of method: String net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator.getPropertyPrefix()
  }

}    //#pebbleapiblogentryaggregator.java:: end of class: net.sourceforge.pebble.event.blog.PebbleAPIBlogEntryAggregator
