| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. The ASF licenses this file to You |
| * under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. For additional information regarding |
| * copyright in this work, please see the NOTICE file in the top level |
| * directory of this distribution. |
| */ |
| |
| package org.apache.roller.weblogger.planet.tasks; |
| |
| import java.util.ArrayList; |
| import java.util.Date; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.Set; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.roller.RollerException; |
| import org.apache.roller.planet.business.PlanetManager; |
| import org.apache.roller.planet.pojos.Planet; |
| import org.apache.roller.planet.pojos.PlanetGroup; |
| import org.apache.roller.planet.pojos.Subscription; |
| import org.apache.roller.weblogger.WebloggerException; |
| import org.apache.roller.weblogger.business.GuiceWebloggerProvider; |
| import org.apache.roller.weblogger.business.WebloggerFactory; |
| import org.apache.roller.weblogger.business.WebloggerProvider; |
| import org.apache.roller.weblogger.business.runnable.RollerTask; |
| import org.apache.roller.weblogger.business.runnable.RollerTaskWithLeasing; |
| import org.apache.roller.weblogger.business.startup.WebloggerStartup; |
| import org.apache.roller.weblogger.config.WebloggerConfig; |
| import org.apache.roller.weblogger.pojos.Weblog; |
| |
| |
| /** |
| * This tasks is responsible for ensuring that the planet group 'all' contains |
| * a subscription for every weblogs in the Roller system. It also takes care |
| * of deleting subsctiptions for weblogs that no longer exist. |
| */ |
| public class SyncWebsitesTask extends RollerTaskWithLeasing { |
| private static Log log = LogFactory.getLog(SyncWebsitesTask.class); |
| |
| public static String NAME = "SyncWebsitesTask"; |
| |
| // a unique id for this specific task instance |
| // this is meant to be unique for each client in a clustered environment |
| private String clientId = "unspecifiedClientId"; |
| |
| // a String description of when to start this task |
| private String startTimeDesc = "startOfDay"; |
| |
| // interval at which the task is run, default is 1 day |
| private int interval = RollerTask.DEFAULT_INTERVAL_MINS; |
| |
| // lease time given to ping task lock, default is 30 minutes |
| private int leaseTime = RollerTaskWithLeasing.DEFAULT_LEASE_MINS; |
| |
| public String getClientId() { |
| return clientId; |
| } |
| |
| public Date getStartTime(Date currentTime) { |
| return getAdjustedTime(currentTime, startTimeDesc); |
| } |
| |
| public String getStartTimeDesc() { |
| return startTimeDesc; |
| } |
| |
| public int getInterval() { |
| return this.interval; |
| } |
| |
| public int getLeaseTime() { |
| return this.leaseTime; |
| } |
| |
| |
| public void init() throws WebloggerException { |
| this.init(RefreshRollerPlanetTask.NAME); |
| } |
| |
| @Override |
| public void init(String name) throws WebloggerException { |
| super.init(name); |
| |
| // get relevant props |
| Properties props = this.getTaskProperties(); |
| |
| // extract clientId |
| String client = props.getProperty("clientId"); |
| if(client != null) { |
| this.clientId = client; |
| } |
| |
| // extract start time |
| String startTimeStr = props.getProperty("startTime"); |
| if(startTimeStr != null) { |
| this.startTimeDesc = startTimeStr; |
| } |
| |
| // extract interval |
| String intervalStr = props.getProperty("interval"); |
| if(intervalStr != null) { |
| try { |
| this.interval = Integer.parseInt(intervalStr); |
| } catch (NumberFormatException ex) { |
| log.warn("Invalid interval: "+intervalStr); |
| } |
| } |
| |
| // extract lease time |
| String leaseTimeStr = props.getProperty("leaseTime"); |
| if(leaseTimeStr != null) { |
| try { |
| this.leaseTime = Integer.parseInt(leaseTimeStr); |
| } catch (NumberFormatException ex) { |
| log.warn("Invalid leaseTime: "+leaseTimeStr); |
| } |
| } |
| } |
| |
| |
| /** |
| * Ensure there's a subscription in the "all" group for every Roller weblog. |
| */ |
| public void runTask() { |
| |
| log.info("Syncing local weblogs with planet subscriptions list"); |
| |
| try { |
| PlanetManager pmgr = WebloggerFactory.getWeblogger().getPlanetManager(); |
| |
| // first, make sure there is an "all" pmgr group |
| Planet planetObject = pmgr.getWebloggerById("zzz_default_planet_zzz"); |
| PlanetGroup group = pmgr.getGroup(planetObject, "all"); |
| if (group == null) { |
| group = new PlanetGroup(); |
| group.setPlanet(planetObject); |
| group.setHandle("all"); |
| group.setTitle("all"); |
| pmgr.saveGroup(group); |
| WebloggerFactory.getWeblogger().flush(); |
| } |
| |
| // walk through all enable weblogs and add/update subs as needed |
| List<String> liveUserFeeds = new ArrayList<String>(); |
| List<Weblog> websites = WebloggerFactory.getWeblogger() |
| .getWeblogManager().getWeblogs(Boolean.TRUE, Boolean.TRUE, null, null, 0, -1); |
| for ( Weblog weblog : websites ) { |
| |
| log.debug("processing weblog - "+weblog.getHandle()); |
| String feedUrl = "weblogger:"+weblog.getHandle(); |
| |
| // add feed url to the "live" list |
| liveUserFeeds.add(feedUrl); |
| |
| // if sub already exists then update it, otherwise add it |
| Subscription sub = pmgr.getSubscription(feedUrl); |
| if (sub == null) { |
| log.debug("ADDING feed: "+feedUrl); |
| |
| sub = new Subscription(); |
| sub.setTitle(weblog.getName()); |
| sub.setFeedURL(feedUrl); |
| sub.setSiteURL( |
| WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogURL(weblog, null, true)); |
| sub.setAuthor(weblog.getName()); |
| sub.setLastUpdated(new Date(0)); |
| pmgr.saveSubscription(sub); |
| |
| sub.getGroups().add(group); |
| group.getSubscriptions().add(sub); |
| |
| pmgr.saveGroup(group); |
| |
| } else { |
| log.debug("UPDATING feed: "+feedUrl); |
| |
| sub.setTitle(weblog.getName()); |
| sub.setAuthor(weblog.getName()); |
| |
| pmgr.saveSubscription(sub); |
| } |
| |
| // save as we go |
| WebloggerFactory.getWeblogger().flush(); |
| } |
| |
| // new subs added, existing subs updated, now delete old subs |
| Set<Subscription> deleteSubs = new HashSet<Subscription>(); |
| Set<Subscription> subs = group.getSubscriptions(); |
| for (Subscription sub : subs) { |
| // only delete subs from the group if ... |
| // 1. they are local |
| // 2. they are no longer listed as a weblog |
| if (sub.getFeedURL().startsWith("weblogger:") && |
| !liveUserFeeds.contains(sub.getFeedURL())) { |
| deleteSubs.add(sub); |
| } |
| } |
| |
| // now go back through deleteSubs and do actual delete |
| // this is required because deleting a sub in the loop above |
| // causes a ConcurrentModificationException because we can't |
| // modify a collection while we iterate over it |
| for (Subscription deleteSub : deleteSubs) { |
| log.debug("DELETING feed: "+deleteSub.getFeedURL()); |
| pmgr.deleteSubscription(deleteSub); |
| group.getSubscriptions().remove(deleteSub); |
| } |
| |
| // all done, lets save |
| pmgr.saveGroup(group); |
| WebloggerFactory.getWeblogger().flush(); |
| |
| } catch (RollerException e) { |
| log.error("ERROR refreshing entries", e); |
| } finally { |
| // don't forget to release |
| WebloggerFactory.getWeblogger().release(); |
| } |
| } |
| |
| |
| /** |
| * Task may be run from the command line |
| */ |
| public static void main(String[] args) throws Exception { |
| |
| // before we can do anything we need to bootstrap the planet backend |
| WebloggerStartup.prepare(); |
| |
| // we need to use our own planet provider for integration |
| String guiceModule = WebloggerConfig.getProperty("planet.aggregator.guice.module"); |
| WebloggerProvider provider = new GuiceWebloggerProvider(guiceModule); |
| WebloggerFactory.bootstrap(provider); |
| |
| SyncWebsitesTask task = new SyncWebsitesTask(); |
| task.init(); |
| task.run(); |
| } |
| |
| } |