001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2009 SonarSource SA
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.api.database.daos;
021    
022    import org.sonar.api.database.DatabaseSession;
023    import org.sonar.api.database.model.AsyncMeasureSnapshot;
024    import org.sonar.api.database.model.MeasureModel;
025    import org.sonar.api.database.model.Snapshot;
026    
027    import java.util.*;
028    
029    public class AsyncMeasuresService {
030      private final DatabaseSession session;
031    
032      public AsyncMeasuresService(DatabaseSession session) {
033        this.session = session;
034      }
035    
036      public void refresh(Snapshot snapshot) {
037        AsyncMeasuresDao dao = new AsyncMeasuresDao(session);
038        Snapshot previousSnapshot = dao.getPreviousSnapshot(snapshot);
039        Date datePreviousSnapshot = (previousSnapshot != null ? previousSnapshot.getCreatedAt() : null);
040    
041        List<AsyncMeasureSnapshot> previousAsyncMeasureSnapshots = dao.getPreviousAsyncMeasureSnapshots(
042            snapshot.getResource().getId(), datePreviousSnapshot, snapshot.getCreatedAt());
043        if (previousSnapshot != null) {
044          previousAsyncMeasureSnapshots.addAll(dao.getAsyncMeasureSnapshotsFromSnapshotId(
045              previousSnapshot.getId(), getMetricIds(previousAsyncMeasureSnapshots)));
046        }
047    
048        for (AsyncMeasureSnapshot asyncMeasureSnapshot : purge(previousAsyncMeasureSnapshots)) {
049          if (asyncMeasureSnapshot.getSnapshotId() == null) {
050            dao.updateAsyncMeasureSnapshot(asyncMeasureSnapshot, snapshot);
051          } else {
052            dao.createAsyncMeasureSnapshot(
053                asyncMeasureSnapshot.getMeasureId(), snapshot.getId(), asyncMeasureSnapshot.getMeasureDate(),
054                snapshot.getCreatedAt(), asyncMeasureSnapshot.getMetricId(), asyncMeasureSnapshot.getProjectId());
055          }
056        }
057        session.commit();
058      }
059    
060      public void registerMeasure(Integer id) {
061        AsyncMeasuresDao dao = new AsyncMeasuresDao(session);
062        registerMeasure(dao.getAsyncMeasure(id), dao);
063      }
064    
065      private List<Integer> getMetricIds(List<AsyncMeasureSnapshot> list) {
066        List<Integer> ids = new ArrayList<Integer>();
067        for (AsyncMeasureSnapshot ams : list) {
068          ids.add(ams.getMetricId());
069        }
070        return ids;
071      }
072    
073      private Collection<AsyncMeasureSnapshot> purge(List<AsyncMeasureSnapshot> list) {
074        Map<Integer, AsyncMeasureSnapshot> measuresById = new LinkedHashMap<Integer, AsyncMeasureSnapshot>();
075        for (AsyncMeasureSnapshot currentAsyncMeasureSnapshot : list) {
076          AsyncMeasureSnapshot asyncMeasureSnapshotFromMap = measuresById.get(currentAsyncMeasureSnapshot.getMetricId());
077          if (asyncMeasureSnapshotFromMap != null) {
078            if (asyncMeasureSnapshotFromMap.getMeasureDate().before(currentAsyncMeasureSnapshot.getMeasureDate())) {
079              measuresById.put(currentAsyncMeasureSnapshot.getMetricId(), currentAsyncMeasureSnapshot);
080            }
081          } else {
082            measuresById.put(currentAsyncMeasureSnapshot.getMetricId(), currentAsyncMeasureSnapshot);
083          }
084        }
085        return measuresById.values();
086      }
087    
088    
089      public void deleteMeasure(Integer id) {
090        AsyncMeasuresDao dao = new AsyncMeasuresDao(session);
091        MeasureModel measure = dao.getAsyncMeasure(id);
092        AsyncMeasureSnapshot pastAsyncMeasureSnapshot = dao.getLastAsyncMeasureSnapshot(measure.getProjectId(),
093            measure.getMetric().getId(), measure.getMeasureDate());
094        dao.deleteAsyncMeasure(measure);
095        if (pastAsyncMeasureSnapshot != null) {
096          MeasureModel pastAsyncMeasure = dao.getAsyncMeasure(pastAsyncMeasureSnapshot.getMeasureId());
097          dao.deleteAsyncMeasureSnapshots(pastAsyncMeasureSnapshot.getMeasureId());
098          registerMeasure(pastAsyncMeasure, dao);
099        }
100        session.commit();
101      }
102    
103      private void registerMeasure(MeasureModel measure, AsyncMeasuresDao dao) {
104        AsyncMeasureSnapshot nextAsyncMeasureSnapshot = dao.getNextAsyncMeasureSnapshot(
105            measure.getProjectId(), measure.getMetric().getId(), measure.getMeasureDate());
106        Date dateNextAsyncMeasure = (nextAsyncMeasureSnapshot != null) ? nextAsyncMeasureSnapshot.getMeasureDate() : null;
107    
108        List<AsyncMeasureSnapshot> nextAsyncMeasureSnapshots = dao.getNextAsyncMeasureSnapshotsUntilDate(
109            measure, dateNextAsyncMeasure);
110        if (!nextAsyncMeasureSnapshots.isEmpty()) {
111          for (AsyncMeasureSnapshot asyncMeasureSnapshot : nextAsyncMeasureSnapshots) {
112            dao.createAsyncMeasureSnapshot(measure.getId(), asyncMeasureSnapshot.getSnapshotId(), measure.getMeasureDate(),
113                asyncMeasureSnapshot.getSnapshotDate(), measure.getMetric().getId(), measure.getProjectId());
114            dao.removeSnapshotFromAsyncMeasureSnapshot(asyncMeasureSnapshot);
115          }
116        } else {
117          List<Snapshot> nextSnapshotsUntilDate = dao.getNextSnapshotsUntilDate(measure, dateNextAsyncMeasure);
118          if (!nextSnapshotsUntilDate.isEmpty()) {
119            for (Snapshot nextSnapshot : nextSnapshotsUntilDate) {
120              dao.createAsyncMeasureSnapshot(measure.getId(), nextSnapshot.getId(), measure.getMeasureDate(),
121                  nextSnapshot.getCreatedAt(), measure.getMetric().getId(), measure.getProjectId());
122            }
123          } else {
124            dao.createAsyncMeasureSnapshot(measure.getId(), null, measure.getMeasureDate(),
125                null, measure.getMetric().getId(), measure.getProjectId());
126          }
127        }
128      }
129    
130    }