001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.plugins.dbcleaner.period; 021 022 import com.google.common.collect.Lists; 023 import org.slf4j.Logger; 024 import org.slf4j.LoggerFactory; 025 import org.sonar.api.database.DatabaseSession; 026 import org.sonar.api.database.model.Snapshot; 027 import org.sonar.api.resources.Project; 028 import org.sonar.plugins.dbcleaner.api.PeriodCleaner; 029 import org.sonar.plugins.dbcleaner.api.PurgeUtils; 030 031 import java.text.DateFormat; 032 import java.util.Date; 033 import java.util.GregorianCalendar; 034 import java.util.List; 035 036 public final class DefaultPeriodCleaner implements PeriodCleaner { 037 038 private static final Logger LOG = LoggerFactory.getLogger(DefaultPeriodCleaner.class); 039 private final SQLRequests sql; 040 private DatabaseSession session; 041 042 public DefaultPeriodCleaner(DatabaseSession session) { 043 this.session = session; 044 this.sql = new SQLRequests(session); 045 } 046 047 public void purge(Project project, int projectSnapshotId) { 048 Periods periods = new Periods(project); 049 periods.log(); 050 purge(project, projectSnapshotId, periods); 051 } 052 053 void purge(Project project, int projectSnapshotId, Periods periods) { 054 List<SnapshotFilter> filters = newFilters(periods); 055 List<Snapshot> snapshotHistory = selectProjectSnapshots(project, projectSnapshotId); 056 applyFilters(snapshotHistory, filters); 057 deleteSnapshotsAndAllRelatedData(snapshotHistory); 058 } 059 060 private List<Snapshot> selectProjectSnapshots(Project project, int snapshotId) { 061 List<Snapshot> snapshotHistory = Lists.newLinkedList(sql.getProjectSnapshotsOrderedByCreatedAt(snapshotId)); 062 LOG.debug("The project '" + project.getName() + "' has " + snapshotHistory.size() + " snapshots."); 063 return snapshotHistory; 064 } 065 066 private void deleteSnapshotsAndAllRelatedData(List<Snapshot> snapshotHistory) { 067 if (snapshotHistory.isEmpty()) { 068 LOG.info("There are no snapshots to purge"); 069 return; 070 } 071 072 List<Integer> ids = Lists.newArrayList(); 073 for (Snapshot snapshot : snapshotHistory) { 074 ids.addAll(sql.getChildIds(snapshot)); 075 } 076 LOG.info("There are " + snapshotHistory.size() + " snapshots and " + (ids.size() - snapshotHistory.size()) 077 + " children snapshots which are obsolete and are going to be deleted."); 078 if (LOG.isDebugEnabled()) { 079 DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); 080 for (Snapshot snapshot : snapshotHistory) { 081 LOG.debug("Delete snapshot created at " + format.format(snapshot.getCreatedAt())); 082 } 083 } 084 PurgeUtils.deleteSnapshotsData(session, ids); 085 } 086 087 private void applyFilters(List<Snapshot> snapshotHistory, List<SnapshotFilter> filters) { 088 for (SnapshotFilter filter : filters) { 089 filter.filter(snapshotHistory); 090 } 091 } 092 093 private List<SnapshotFilter> newFilters(Periods periods) { 094 List<SnapshotFilter> filters = Lists.newArrayList(); 095 filters.add(new KeepLibrarySnapshotFilter()); 096 filters.add(new KeepSnapshotsBetweenTwoDatesFilter(new Date(), periods.dateToStartKeepingOneSnapshotByWeek)); 097 filters.add(new KeepOneSnapshotByPeriodBetweenTwoDatesFilter(GregorianCalendar.WEEK_OF_YEAR, 098 periods.dateToStartKeepingOneSnapshotByWeek, 099 periods.dateToStartKeepingOneSnapshotByMonth)); 100 filters.add(new KeepOneSnapshotByPeriodBetweenTwoDatesFilter(GregorianCalendar.MONTH, 101 periods.dateToStartKeepingOneSnapshotByMonth, 102 periods.dateToStartDeletingAllSnapshots)); 103 filters.add(new KeepLastSnapshotFilter()); 104 return filters; 105 } 106 }