3 * see AUTHORS for the list of contributors
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package org.sonews.util;
21 import java.util.Date;
22 import java.util.List;
23 import org.sonews.daemon.AbstractDaemon;
24 import org.sonews.config.Config;
25 import org.sonews.storage.Article;
26 import org.sonews.storage.Headers;
27 import org.sonews.storage.Channel;
28 import org.sonews.storage.Group;
29 import org.sonews.storage.StorageBackendException;
30 import org.sonews.storage.StorageManager;
33 * The purger is started in configurable intervals to search
34 * for messages that can be purged. A message must be deleted if its lifetime
35 * has exceeded, if it was marked as deleted or if the maximum number of
36 * articles in the database is reached.
37 * @author Christian Lins
40 public class Purger extends AbstractDaemon
44 * Loops through all messages and deletes them if their time
55 Thread.sleep(120000); // Sleep for two minutes
57 } catch (StorageBackendException ex) {
59 } catch (InterruptedException ex) {
60 Log.get().warning("Purger interrupted: " + ex);
64 private void purgeDeleted()
65 throws StorageBackendException
67 List<Channel> groups = StorageManager.current().getGroups();
68 for (Channel channel : groups) {
69 if (!(channel instanceof Group)) {
73 Group group = (Group) channel;
74 // Look for groups that are marked as deleted
75 if (group.isDeleted()) {
76 List<Long> ids = StorageManager.current().getArticleNumbers(group.getInternalID());
77 if (ids.size() == 0) {
78 StorageManager.current().purgeGroup(group);
79 Log.get().info("Group " + group.getName() + " purged.");
82 for (int n = 0; n < ids.size() && n < 10; n++) {
83 Article art = StorageManager.current().getArticle(ids.get(n), group.getInternalID());
84 StorageManager.current().delete(art.getMessageID());
85 Log.get().info("Article " + art.getMessageID() + " purged.");
91 private void purgeOutdated()
92 throws InterruptedException, StorageBackendException
95 Config.inst().get("sonews.article.maxnum", Long.MAX_VALUE);
97 Config.inst().get("sonews.article.lifetime", -1);
99 if (lifetime > 0 || articleMaximum < Stats.getInstance().getNumberOfNews()) {
100 Log.get().info("Purging old messages...");
101 String mid = StorageManager.current().getOldestArticle();
102 if (mid == null) // No articles in the database
107 Article art = StorageManager.current().getArticle(mid);
109 String dateStr = art.getHeader(Headers.DATE)[0];
111 artDate = Date.parse(dateStr) / 1000 / 60 / 60 / 24;
112 } catch (IllegalArgumentException ex) {
113 Log.get().warning("Could not parse date string: " + dateStr + " " + ex);
116 // Should we delete the message because of its age or because the
117 // article maximum was reached?
118 if (lifetime < 0 || artDate < (new Date().getTime() + lifetime)) {
119 StorageManager.current().delete(mid);
120 System.out.println("Deleted: " + mid);
122 Thread.sleep(1000 * 60); // Wait 60 seconds
126 Log.get().info("Lifetime purger is disabled");
127 Thread.sleep(1000 * 60 * 30); // Wait 30 minutes