001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.batch.index;
021
022 import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
023 import org.sonar.api.database.model.MeasureMapper;
024 import org.sonar.api.database.model.MeasureModel;
025 import org.sonar.api.database.model.Snapshot;
026 import org.sonar.api.measures.CoreMetrics;
027 import org.sonar.api.measures.Measure;
028 import org.sonar.api.measures.PersistenceMode;
029 import org.sonar.api.resources.Resource;
030 import org.sonar.api.rules.RuleFinder;
031 import org.sonar.batch.duplication.DuplicationCache;
032 import org.sonar.batch.duplication.DuplicationUtils;
033 import org.sonar.batch.index.Cache.Entry;
034 import org.sonar.core.persistence.DbSession;
035 import org.sonar.core.persistence.MyBatis;
036
037 import java.util.List;
038
039 public final class DuplicationPersister implements ScanPersister {
040 private final MyBatis mybatis;
041 private final RuleFinder ruleFinder;
042 private final SnapshotCache snapshotCache;
043 private final ResourceCache resourceCache;
044 private final DuplicationCache duplicationCache;
045 private final org.sonar.api.measures.MetricFinder metricFinder;
046
047 public DuplicationPersister(MyBatis mybatis, RuleFinder ruleFinder,
048 SnapshotCache snapshotCache, ResourceCache resourceCache,
049 DuplicationCache duplicationCache, org.sonar.api.measures.MetricFinder metricFinder) {
050 this.mybatis = mybatis;
051 this.ruleFinder = ruleFinder;
052 this.snapshotCache = snapshotCache;
053 this.resourceCache = resourceCache;
054 this.duplicationCache = duplicationCache;
055 this.metricFinder = metricFinder;
056 }
057
058 @Override
059 public void persist() {
060 // Don't use batch insert for duplications since keeping all data in memory can produce OOM
061 DbSession session = mybatis.openSession(false);
062 try {
063 MeasureMapper mapper = session.getMapper(MeasureMapper.class);
064 org.sonar.api.measures.Metric duplicationMetricWithId = metricFinder.findByKey(CoreMetrics.DUPLICATIONS_DATA_KEY);
065 for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) {
066 String effectiveKey = entry.key()[0].toString();
067 Measure measure = new Measure(duplicationMetricWithId, DuplicationUtils.toXml(entry.value())).setPersistenceMode(PersistenceMode.DATABASE);
068 Resource resource = resourceCache.get(effectiveKey);
069
070 if (MeasurePersister.shouldPersistMeasure(resource, measure)) {
071 Snapshot snapshot = snapshotCache.get(effectiveKey);
072 MeasureModel measureModel = MeasurePersister.model(measure, ruleFinder).setSnapshotId(snapshot.getId());
073 mapper.insert(measureModel);
074 }
075 }
076
077 session.commit();
078 } catch (Exception e) {
079 throw new IllegalStateException("Unable to save some measures", e);
080 } finally {
081 MyBatis.closeQuietly(session);
082 }
083 }
084
085 }