File Source: SyncWebsitesTask.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.planet.tasks;
    20  
    21  import java.util.ArrayList;
    22  import java.util.Date;
    23  import java.util.HashSet;
    24  import java.util.List;
    25  import java.util.Properties;
    26  import java.util.Set;
    27  import org.apache.commons.logging.Log;
    28  import org.apache.commons.logging.LogFactory;
    29  import org.apache.roller.RollerException;
    30  import org.apache.roller.planet.business.GuicePlanetProvider;
    31  import org.apache.roller.planet.business.PlanetFactory;
    32  import org.apache.roller.planet.business.PlanetManager;
    33  import org.apache.roller.planet.business.PlanetProvider;
    34  import org.apache.roller.planet.business.startup.PlanetStartup;
    35  import org.apache.roller.planet.pojos.Planet;
    36  import org.apache.roller.planet.pojos.PlanetGroup;
    37  import org.apache.roller.planet.pojos.Subscription;
    38  import org.apache.roller.weblogger.WebloggerException;
    39  import org.apache.roller.weblogger.business.UserManager;
    40  import org.apache.roller.weblogger.business.WebloggerFactory;
    41  import org.apache.roller.weblogger.business.runnable.RollerTaskWithLeasing;
    42  import org.apache.roller.weblogger.config.WebloggerConfig;
    43  import org.apache.roller.weblogger.pojos.Weblog;
    44  
    45  
    46  /**
    47   * This tasks is responsible for ensuring that the planet group 'all' contains
    48   * a subscription for every weblogs in the Roller system. It also takes care 
    49   * of deleting subsctiptions for weblogs that no longer exist.
    50   */
         /* 
    P/P   *  Method: void org.apache.roller.weblogger.planet.tasks.SyncWebsitesTask()
          * 
          *  Postconditions:
          *    this.clientId == &"unspecifiedClientId"
          *    this.interval == 1_440
          *    this.leaseTime == 30
          *    this.startTimeDesc == &"startOfDay"
          */
    51  public class SyncWebsitesTask extends RollerTaskWithLeasing {
    52      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.planet.tasks.SyncWebsitesTask__static_init
              * 
              *  Postconditions:
              *    init'ed(log)
              */
    53      private static Log log = LogFactory.getLog(SyncWebsitesTask.class);
    54      
    55      // a unique id for this specific task instance
    56      // this is meant to be unique for each client in a clustered environment
    57      private String clientId = "unspecifiedClientId";
    58      
    59      // a String description of when to start this task
    60      private String startTimeDesc = "startOfDay";
    61      
    62      // interval at which the task is run, default is 1 day
    63      private int interval = 1440;
    64      
    65      // lease time given to ping task lock, default is 30 minutes
    66      private int leaseTime = 30;
    67      
    68      
    69      public String getName() {
                 /* 
    P/P           *  Method: String getName()
                  * 
                  *  Postconditions:
                  *    return_value == &"SyncWebsitesTask"
                  */
    70          return "SyncWebsitesTask";
    71      }
    72      
    73      public String getClientId() {
                 /* 
    P/P           *  Method: String getClientId()
                  * 
                  *  Preconditions:
                  *    init'ed(this.clientId)
                  * 
                  *  Postconditions:
                  *    return_value == this.clientId
                  *    init'ed(return_value)
                  */
    74          return clientId;
    75      }
    76      
    77      public Date getStartTime(Date currentTime) {
                 /* 
    P/P           *  Method: Date getStartTime(Date)
                  * 
                  *  Preconditions:
                  *    init'ed(this.startTimeDesc)
                  * 
                  *  Postconditions:
                  *    init'ed(return_value)
                  */
    78          return getAdjustedTime(currentTime, startTimeDesc);
    79      }
    80      
    81      public String getStartTimeDesc() {
                 /* 
    P/P           *  Method: String getStartTimeDesc()
                  * 
                  *  Preconditions:
                  *    init'ed(this.startTimeDesc)
                  * 
                  *  Postconditions:
                  *    return_value == this.startTimeDesc
                  *    init'ed(return_value)
                  */
    82          return startTimeDesc;
    83      }
    84      
    85      public int getInterval() {
                 /* 
    P/P           *  Method: int getInterval()
                  * 
                  *  Preconditions:
                  *    init'ed(this.interval)
                  * 
                  *  Postconditions:
                  *    return_value == this.interval
                  *    init'ed(return_value)
                  */
    86          return this.interval;
    87      }
    88      
    89      public int getLeaseTime() {
                 /* 
    P/P           *  Method: int getLeaseTime()
                  * 
                  *  Preconditions:
                  *    init'ed(this.leaseTime)
                  * 
                  *  Postconditions:
                  *    return_value == this.leaseTime
                  *    init'ed(return_value)
                  */
    90          return this.leaseTime;
    91      }
    92      
    93      
    94      public void init() throws WebloggerException {
    95          
    96          // get relevant props
                 /* 
    P/P           *  Method: void init()
                  * 
                  *  Preconditions:
                  *    (soft) log != null
                  * 
                  *  Presumptions:
                  *    org.apache.roller.weblogger.planet.tasks.SyncWebsitesTask:getTaskProperties(...)@97 != null
                  * 
                  *  Postconditions:
                  *    possibly_updated(this.clientId)
                  *    possibly_updated(this.interval)
                  *    possibly_updated(this.leaseTime)
                  *    possibly_updated(this.startTimeDesc)
                  * 
                  *  Test Vectors:
                  *    java.util.Properties:getProperty(...)@100: Addr_Set{null}, Inverse{null}
                  *    java.util.Properties:getProperty(...)@106: Addr_Set{null}, Inverse{null}
                  *    java.util.Properties:getProperty(...)@112: Addr_Set{null}, Inverse{null}
                  *    java.util.Properties:getProperty(...)@122: Addr_Set{null}, Inverse{null}
                  */
    97          Properties props = this.getTaskProperties();
    98          
    99          // extract clientId
   100          String client = props.getProperty("clientId");
   101          if(client != null) {
   102              this.clientId = client;
   103          }
   104          
   105          // extract start time
   106          String startTimeStr = props.getProperty("startTime");
   107          if(startTimeStr != null) {
   108              this.startTimeDesc = startTimeStr;
   109          }
   110          
   111          // extract interval
   112          String intervalStr = props.getProperty("interval");
   113          if(intervalStr != null) {
   114              try {
   115                  this.interval = Integer.parseInt(intervalStr);
   116              } catch (NumberFormatException ex) {
   117                  log.warn("Invalid interval: "+intervalStr);
   118              }
   119          }
   120          
   121          // extract lease time
   122          String leaseTimeStr = props.getProperty("leaseTime");
   123          if(leaseTimeStr != null) {
   124              try {
   125                  this.leaseTime = Integer.parseInt(leaseTimeStr);
   126              } catch (NumberFormatException ex) {
   127                  log.warn("Invalid leaseTime: "+leaseTimeStr);
   128              }
   129          }
   130      }
   131      
   132      
   133      /**
   134       * Ensure there's a subscription in the "all" group for every Roller weblog.
   135       */
   136      public void runTask() {
   137          
                 /* 
    P/P           *  Method: void runTask()
                  * 
                  *  Preconditions:
                  *    log != null
                  * 
                  *  Presumptions:
                  *    init'ed(java.lang.Boolean.TRUE)
                  *    java.util.Iterator:next(...)@158 != null
                  *    java.util.Iterator:next(...)@197 != null
                  *    java.util.Iterator:next(...)@212 != null
                  *    org.apache.roller.planet.business.Planet:getPlanetManager(...)@141 != null
                  *    ...
                  * 
                  *  Test Vectors:
                  *    java.lang.String:startsWith(...)@202: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@158: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@197: {0}, {1}
                  *    java.util.Iterator:hasNext(...)@212: {0}, {1}
                  *    java.util.List:contains(...)@202: {1}, {0}
                  *    org.apache.roller.planet.business.PlanetManager:getGroup(...)@146: Inverse{null}, Addr_Set{null}
                  *    org.apache.roller.planet.business.PlanetManager:getSubscription(...)@167: Inverse{null}, Addr_Set{null}
                  */
   138          log.info("Syncing local weblogs with planet subscriptions list");
   139          
   140          try {
   141              PlanetManager pmgr = PlanetFactory.getPlanet().getPlanetManager();
   142              UserManager userManager = WebloggerFactory.getWeblogger().getUserManager();
   143              
   144              // first, make sure there is an "all" pmgr group
   145              Planet planetObject = pmgr.getPlanetById("zzz_default_planet_zzz");
   146              PlanetGroup group = pmgr.getGroup(planetObject, "all");
   147              if(group == null) {
   148                  group = new PlanetGroup();
   149                  group.setPlanet(planetObject);
   150                  group.setHandle("all");
   151                  group.setTitle("all");
   152                  pmgr.saveGroup(group);
   153              }
   154              
   155              // walk through all enable weblogs and add/update subs as needed
   156              List liveUserFeeds = new ArrayList();
   157              List<Weblog> websites = userManager.getWebsites(null, Boolean.TRUE, Boolean.TRUE, null, null, 0, -1);
   158              for ( Weblog weblog : websites ) {
   159                  
   160                  log.debug("processing weblog - "+weblog.getHandle());
   161                  String feedUrl = "weblogger:"+weblog.getHandle();
   162                  
   163                  // add feed url to the "live" list
   164                  liveUserFeeds.add(feedUrl);
   165                  
   166                  // if sub already exists then update it, otherwise add it
   167                  Subscription sub = pmgr.getSubscription(feedUrl);
   168                  if (sub == null) {
   169                      log.debug("ADDING feed: "+feedUrl);
   170                      
   171                      sub = new Subscription();
   172                      sub.setTitle(weblog.getName());
   173                      sub.setFeedURL(feedUrl);
   174                      sub.setSiteURL(WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogURL(weblog, null, true));
   175                      sub.setAuthor(weblog.getName());
   176                      sub.setLastUpdated(new Date(0));
   177                      
   178                      pmgr.saveSubscription(sub);
   179                      group.getSubscriptions().add(sub);
   180                      pmgr.saveGroup(group);
   181                  } else {
   182                      log.debug("UPDATING feed: "+feedUrl);
   183                      
   184                      sub.setTitle(weblog.getName());
   185                      sub.setAuthor(weblog.getName());
   186                      
   187                      pmgr.saveSubscription(sub);
   188                  }
   189                  
   190                  // save as we go
   191                  PlanetFactory.getPlanet().flush();
   192              }
   193              
   194              // new subs added, existing subs updated, now delete old subs
   195              Set<Subscription> deleteSubs = new HashSet();
   196              Set<Subscription> subs = group.getSubscriptions();
   197              for( Subscription sub : subs ) {
   198                  
   199                  // only delete subs from the group if ...
   200                  // 1. they are local
   201                  // 2. they are no longer listed as a weblog 
   202                  if (sub.getFeedURL().startsWith("weblogger:") && 
   203                          !liveUserFeeds.contains(sub.getFeedURL())) {
   204                      deleteSubs.add(sub);
   205                  }
   206              }
   207              
   208              // now go back through deleteSubs and do actual delete
   209              // this is required because deleting a sub in the loop above
   210              // causes a ConcurrentModificationException because we can't
   211              // modify a collection while we iterate over it
   212              for( Subscription deleteSub : deleteSubs ) {
   213                  
   214                  log.debug("DELETING feed: "+deleteSub.getFeedURL());
   215                  pmgr.deleteSubscription(deleteSub);
   216                  group.getSubscriptions().remove(deleteSub);
   217              }
   218              
   219              // all done, lets save
   220              pmgr.saveGroup(group);
   221              PlanetFactory.getPlanet().flush();
   222              
   223          } catch (RollerException e) {
   224              log.error("ERROR refreshing entries", e);
   225          } finally {
   226              // don't forget to release
   227              WebloggerFactory.getWeblogger().release();
   228              PlanetFactory.getPlanet().release();
   229          }
   230      }
   231      
   232      
   233      /** 
   234       * Task may be run from the command line 
   235       */
   236      public static void main(String[] args) throws Exception {
   237          
   238          // before we can do anything we need to bootstrap the planet backend
                 /* 
    P/P           *  Method: void main(String[])
                  * 
                  *  Preconditions:
                  *    (soft) log != null
                  */
   239          PlanetStartup.prepare();
   240          
   241          // we need to use our own planet provider for integration
   242          String guiceModule = WebloggerConfig.getProperty("planet.aggregator.guice.module");
   243          PlanetProvider provider = new GuicePlanetProvider(guiceModule);
   244          PlanetFactory.bootstrap(provider);
   245          
   246          SyncWebsitesTask task = new SyncWebsitesTask();
   247          task.init();
   248          task.run();
   249      }
   250      
   251  }








SofCheck Inspector Build Version : 2.18479
SyncWebsitesTask.java 2009-Jan-02 14:24:44
SyncWebsitesTask.class 2009-Sep-04 03:12:46