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.scan2;
021
022 import com.google.common.base.Preconditions;
023 import org.sonar.api.batch.fs.FileSystem;
024 import org.sonar.api.batch.fs.InputFile;
025 import org.sonar.api.batch.fs.internal.DefaultInputFile;
026 import org.sonar.api.batch.rule.ActiveRules;
027 import org.sonar.api.batch.sensor.SensorContext;
028 import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
029 import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
030 import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
031 import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
032 import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
033 import org.sonar.api.batch.sensor.issue.IssueBuilder;
034 import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
035 import org.sonar.api.batch.sensor.measure.MeasureBuilder;
036 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
037 import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
038 import org.sonar.api.config.Settings;
039 import org.sonar.batch.duplication.BlockCache;
040 import org.sonar.batch.duplication.DefaultTokenBuilder;
041 import org.sonar.batch.duplication.DuplicationCache;
042 import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
043 import org.sonar.batch.index.ComponentDataCache;
044 import org.sonar.batch.scan.SensorContextAdaptor;
045 import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
046 import org.sonar.duplications.internal.pmd.PmdBlockChunker;
047
048 import java.io.Serializable;
049 import java.util.List;
050
051 /**
052 * Common bits between {@link DefaultSensorContext} and {@link SensorContextAdaptor}
053 * @author julien
054 *
055 */
056 public abstract class BaseSensorContext implements SensorContext {
057
058 private final Settings settings;
059 private final FileSystem fs;
060 private final ActiveRules activeRules;
061 private final ComponentDataCache componentDataCache;
062 private final BlockCache blockCache;
063 private final DuplicationCache duplicationCache;
064
065 protected BaseSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache,
066 BlockCache blockCache, DuplicationCache duplicationCache) {
067 this.settings = settings;
068 this.fs = fs;
069 this.activeRules = activeRules;
070 this.componentDataCache = componentDataCache;
071 this.blockCache = blockCache;
072 this.duplicationCache = duplicationCache;
073 }
074
075 @Override
076 public Settings settings() {
077 return settings;
078 }
079
080 @Override
081 public FileSystem fileSystem() {
082 return fs;
083 }
084
085 @Override
086 public ActiveRules activeRules() {
087 return activeRules;
088 }
089
090 @Override
091 public <G extends Serializable> MeasureBuilder<G> measureBuilder() {
092 return new DefaultMeasureBuilder<G>();
093 }
094
095 @Override
096 public IssueBuilder issueBuilder() {
097 return new DefaultIssueBuilder();
098 }
099
100 @Override
101 public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
102 return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
103 }
104
105 @Override
106 public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
107 return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
108 }
109
110 @Override
111 public DuplicationTokenBuilder duplicationTokenBuilder(InputFile inputFile) {
112 PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
113
114 return new DefaultTokenBuilder(inputFile, blockCache, blockChunker);
115 }
116
117 @Override
118 public DuplicationBuilder duplicationBuilder(InputFile inputFile) {
119 return new DefaultDuplicationBuilder(inputFile);
120 }
121
122 @Override
123 public void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications) {
124 Preconditions.checkState(!duplications.isEmpty(), "Empty duplications");
125 String effectiveKey = ((DefaultInputFile) inputFile).key();
126 for (DuplicationGroup duplicationGroup : duplications) {
127 Preconditions.checkState(effectiveKey.equals(duplicationGroup.originBlock().resourceKey()), "Invalid duplication group");
128 }
129 duplicationCache.put(effectiveKey, duplications);
130 }
131
132 private int getBlockSize(String languageKey) {
133 int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
134 if (blockSize == 0) {
135 blockSize = getDefaultBlockSize(languageKey);
136 }
137 return blockSize;
138 }
139
140 private static int getDefaultBlockSize(String languageKey) {
141 if ("cobol".equals(languageKey)) {
142 return 30;
143 } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
144 return 20;
145 } else {
146 return 10;
147 }
148 }
149
150 }