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 |