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/>.
18 package org.sonews.util;
20 import java.util.Date;
21 import java.util.List;
22 import org.sonews.daemon.AbstractDaemon;
23 import org.sonews.config.Config;
24 import org.sonews.storage.Article;
25 import org.sonews.storage.Headers;
26 import org.sonews.storage.Group;
27 import org.sonews.storage.StorageBackendException;
28 import org.sonews.storage.StorageManager;
31 * The purger is started in configurable intervals to search
32 * for messages that can be purged. A message must be deleted if its lifetime
33 * has exceeded, if it was marked as deleted or if the maximum number of
34 * articles in the database is reached.
35 * @author Christian Lins
38 public class Purger extends AbstractDaemon {
41 * Loops through all messages and deletes them if their time
51 Thread.sleep(120000); // Sleep for two minutes
53 } catch (StorageBackendException ex) {
55 } catch (InterruptedException ex) {
56 Log.get().warning("Purger interrupted: " + ex);
60 private void purgeDeleted()
61 throws StorageBackendException {
62 List<Group> groups = StorageManager.current().getGroups();
63 for (Group channel : groups) {
64 if (!(channel instanceof Group)) {
68 Group group = (Group) channel;
69 // Look for groups that are marked as deleted
70 if (group.isDeleted()) {
71 List<Long> ids = StorageManager.current().getArticleNumbers(group.getInternalID());
72 if (ids.size() == 0) {
73 StorageManager.current().purgeGroup(group);
74 Log.get().info("Group " + group.getName() + " purged.");
77 for (int n = 0; n < ids.size() && n < 10; n++) {
78 Article art = StorageManager.current().getArticle(ids.get(n), group.getInternalID());
79 StorageManager.current().delete(art.getMessageID());
80 Log.get().info("Article " + art.getMessageID() + " purged.");
86 private void purgeOutdated()
87 throws InterruptedException, StorageBackendException {
89 Config.inst().get("sonews.article.maxnum", Long.MAX_VALUE);
91 Config.inst().get("sonews.article.lifetime", -1);
93 if (lifetime > 0 || articleMaximum < Stats.getInstance().getNumberOfNews()) {
94 Log.get().info("Purging old messages...");
95 String mid = StorageManager.current().getOldestArticle();
96 if (mid == null) // No articles in the database
101 Article art = StorageManager.current().getArticle(mid);
103 String dateStr = art.getHeader(Headers.DATE)[0];
105 artDate = Date.parse(dateStr) / 1000 / 60 / 60 / 24;
106 } catch (IllegalArgumentException ex) {
107 Log.get().warning("Could not parse date string: " + dateStr + " " + ex);
110 // Should we delete the message because of its age or because the
111 // article maximum was reached?
112 if (lifetime < 0 || artDate < (new Date().getTime() + lifetime)) {
113 StorageManager.current().delete(mid);
114 System.out.println("Deleted: " + mid);
116 Thread.sleep(1000 * 60); // Wait 60 seconds
120 Log.get().info("Lifetime purger is disabled");
121 Thread.sleep(1000 * 60 * 30); // Wait 30 minutes