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.scan.measure;
021    
022    import com.google.common.base.Preconditions;
023    import org.sonar.api.BatchComponent;
024    import org.sonar.api.measures.Measure;
025    import org.sonar.api.measures.MetricFinder;
026    import org.sonar.api.measures.RuleMeasure;
027    import org.sonar.api.resources.Resource;
028    import org.sonar.api.technicaldebt.batch.Characteristic;
029    import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
030    import org.sonar.batch.index.Cache;
031    import org.sonar.batch.index.Cache.Entry;
032    import org.sonar.batch.index.Caches;
033    
034    /**
035     * Cache of all measures. This cache is shared amongst all project modules.
036     */
037    public class MeasureCache implements BatchComponent {
038    
039      private final Cache<Measure> cache;
040    
041      public MeasureCache(Caches caches, MetricFinder metricFinder, TechnicalDebtModel techDebtModel) {
042        caches.registerValueCoder(Measure.class, new MeasureValueCoder(metricFinder, techDebtModel));
043        cache = caches.createCache("measures");
044      }
045    
046      public Iterable<Entry<Measure>> entries() {
047        return cache.entries();
048      }
049    
050      public Iterable<Measure> byResource(Resource r) {
051        return cache.values(r.getEffectiveKey());
052      }
053    
054      public Iterable<Measure> byMetric(Resource r, String metricKey) {
055        return byMetric(r.getEffectiveKey(), metricKey);
056      }
057    
058      public Iterable<Measure> byMetric(String resourceKey, String metricKey) {
059        return cache.values(resourceKey, metricKey);
060      }
061    
062      public MeasureCache put(Resource resource, Measure measure) {
063        Preconditions.checkNotNull(resource.getEffectiveKey());
064        Preconditions.checkNotNull(measure.getMetricKey());
065        cache.put(resource.getEffectiveKey(), measure.getMetricKey(), computeMeasureKey(measure), measure);
066        return this;
067      }
068    
069      public boolean contains(Resource resource, Measure measure) {
070        Preconditions.checkNotNull(resource.getEffectiveKey());
071        Preconditions.checkNotNull(measure.getMetricKey());
072        return cache.containsKey(resource.getEffectiveKey(), measure.getMetricKey(), computeMeasureKey(measure));
073      }
074    
075      private static String computeMeasureKey(Measure m) {
076        StringBuilder sb = new StringBuilder();
077        if (m.getMetricKey() != null) {
078          sb.append(m.getMetricKey());
079        }
080        sb.append("|");
081        Characteristic characteristic = m.getCharacteristic();
082        if (characteristic != null) {
083          sb.append(characteristic.key());
084        }
085        sb.append("|");
086        Integer personId = m.getPersonId();
087        if (personId != null) {
088          sb.append(personId);
089        }
090        if (m instanceof RuleMeasure) {
091          sb.append("|");
092          sb.append(((RuleMeasure) m).ruleKey());
093        }
094        return sb.toString();
095      }
096    
097    }