import org.sonar.db.component.ComponentLinkMapper;
import org.sonar.db.component.ComponentMapper;
import org.sonar.db.component.FilePathWithHashDto;
+import org.sonar.db.component.KeyWithUuidDto;
import org.sonar.db.component.ResourceDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.component.SnapshotMapper;
confBuilder.loadAlias("DuplicationUnit", DuplicationUnitDto.class);
confBuilder.loadAlias("Event", EventDto.class);
confBuilder.loadAlias("FilePathWithHash", FilePathWithHashDto.class);
+ confBuilder.loadAlias("KeyWithUuid", KeyWithUuidDto.class);
confBuilder.loadAlias("Group", GroupDto.class);
confBuilder.loadAlias("GroupMembership", GroupMembershipDto.class);
confBuilder.loadAlias("GroupPermission", GroupPermissionDto.class);
return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, null, false);
}
+ public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(DbSession session, String projectKey) {
+ return mapper(session).selectUuidsByKeyFromProjectKey(projectKey);
+ }
+
public List<ComponentDto> selectEnabledModulesFromProjectKey(DbSession session, String projectKey) {
return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, Scopes.PROJECT, true);
}
public List<ComponentDto> selectByKeysAndBranch(DbSession session, Collection<String> keys, String branch) {
List<String> dbKeys = keys.stream().map(k -> generateBranchKey(k, branch)).collect(toList());
- List<String> allKeys = Stream.of(keys, dbKeys) .flatMap(Collection::stream) .collect(toList());
+ List<String> allKeys = Stream.of(keys, dbKeys).flatMap(Collection::stream).collect(toList());
return executeLargeInputs(allKeys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, branch));
}
List<ComponentDto> selectComponentsFromProjectKeyAndScope(@Param("projectKey") String projectKey, @Nullable @Param("scope") String scope,
@Param(value = "excludeDisabled") boolean excludeDisabled);
+ /**
+ * Return keys and UUIDs of all components belonging to a project
+ */
+ List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(@Param("projectKey") String projectKey);
+
/**
* Return technical projects from a view or a sub-view
*/
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.component;
+
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
+public class KeyWithUuidDto {
+
+ private final String kee;
+ private final String uuid;
+
+ public KeyWithUuidDto(String kee, String uuid) {
+ this.kee = kee;
+ this.uuid = uuid;
+ }
+
+ public String key() {
+ return kee;
+ }
+
+ public String uuid() {
+ return uuid;
+ }
+}
</if>
</where>
</select>
+
+ <select id="selectUuidsByKeyFromProjectKey" parameterType="string" resultType="KeyWithUuid">
+ SELECT
+ p.kee, p.uuid
+ FROM
+ projects p
+ INNER JOIN
+ projects root ON root.uuid=p.project_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR}
+ </select>
<select id="selectGhostProjects" parameterType="map" resultType="Component">
select distinct
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.assertj.core.api.ListAssert;
import org.junit.Rule;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.tuple;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.sonar.db.component.ComponentTesting.newDirectory;
assertThat(underTest.selectAllComponentsFromProjectKey(dbSession, "UNKNOWN")).isEmpty();
}
+ @Test
+ public void select_uuids_by_key_from_project() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false));
+ ComponentDto module = db.components().insertComponent(newModuleDto(project));
+ ComponentDto removedModule = db.components().insertComponent(newModuleDto(project).setEnabled(false));
+ ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
+ ComponentDto removedSubModule = db.components().insertComponent(newModuleDto(module).setEnabled(false));
+ ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src"));
+ ComponentDto removedDirectory = db.components().insertComponent(newDirectory(subModule, "src2").setEnabled(false));
+ ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory));
+ ComponentDto removedFile = db.components().insertComponent(newFileDto(subModule, directory).setEnabled(false));
+
+ Map<String, String> uuidsByKey = underTest.selectUuidsByKeyFromProjectKey(dbSession, project.getDbKey())
+ .stream().collect(Collectors.toMap(KeyWithUuidDto::key, KeyWithUuidDto::uuid));
+
+ assertThat(uuidsByKey).containsOnly(
+ entry(project.getDbKey(), project.uuid()),
+ entry(module.getDbKey(), module.uuid()),
+ entry(removedModule.getDbKey(), removedModule.uuid()),
+ entry(subModule.getDbKey(), subModule.uuid()),
+ entry(removedSubModule.getDbKey(), removedSubModule.uuid()),
+ entry(directory.getDbKey(), directory.uuid()),
+ entry(removedDirectory.getDbKey(), removedDirectory.uuid()),
+ entry(file.getDbKey(), file.uuid()),
+ entry(removedFile.getDbKey(), removedFile.uuid()));
+ }
+
@Test
public void select_enabled_modules_from_project() {
ComponentDto project = db.components().insertPrivateProject();
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
-import static java.util.Arrays.asList;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.trimToNull;
public Type getType() {
return type;
}
-
+
@Override
public Status getStatus() {
return status;
private static final String REPORT_ATTRIBUTES_CANNOT_BE_NULL = "reportAttributes can't be null";
private static final String NAME_CANNOT_BE_NULL = "name can't be null";
private static final String STATUS_CANNOT_BE_NULL = "status can't be null";
-
+
private final Type type;
private Status status;
private ReportAttributes reportAttributes;
public String getUuid() {
return uuid;
}
-
+
public Builder setStatus(Status status) {
this.status = requireNonNull(status, STATUS_CANNOT_BE_NULL);
return this;
return this;
}
- public Builder addChildren(Component... c) {
- for (Component component : c) {
+ public Builder addChildren(List<Component> components) {
+ for (Component component : components) {
checkArgument(component.getType().isReportType());
}
- this.children.addAll(asList(c));
+ this.children.addAll(components);
return this;
}
*/
package org.sonar.server.computation.task.projectanalysis.component;
+import java.util.List;
import java.util.function.Function;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.db.component.SnapshotDto;
return buildComponent(project, project);
}
- private Component[] buildChildren(ScannerReport.Component component, ScannerReport.Component parentModule) {
+ private List<Component> buildChildren(ScannerReport.Component component, ScannerReport.Component parentModule) {
return component.getChildRefList()
.stream()
.map(scannerComponentSupplier::apply)
.map(c -> buildComponent(c, parentModule))
- .toArray(Component[]::new);
+ .collect(Collectors.toList());
}
private ComponentImpl buildComponent(ScannerReport.Component component, ScannerReport.Component closestModule) {
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.KeyWithUuidDto;
public class ComponentUuidFactory {
private final Map<String, String> uuidsByKey = new HashMap<>();
public ComponentUuidFactory(DbClient dbClient, DbSession dbSession, String rootKey) {
- List<ComponentDto> components = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, rootKey);
- for (ComponentDto dto : components) {
- uuidsByKey.put(dto.getDbKey(), dto.uuid());
+ List<KeyWithUuidDto> keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey);
+ for (KeyWithUuidDto dto : keys) {
+ uuidsByKey.put(dto.key(), dto.uuid());
}
}
import org.sonar.db.component.ComponentTreeQuery;
import org.sonar.db.component.ComponentTreeQuery.Strategy;
import org.sonar.db.source.FileSourceDto;
-import org.sonar.server.computation.task.projectanalysis.analysis.Analysis;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
@Override
public void execute() {
// do nothing if no files in db (first analysis)
- Analysis baseProjectAnalysis = analysisMetadataHolder.getBaseAnalysis();
- if (baseProjectAnalysis == null) {
+ if (analysisMetadataHolder.isFirstAnalysis()) {
LOG.debug("First analysis. Do nothing.");
return;
}
public List<DefaultIssue> getIssues(Component component) {
checkState(this.component != null && this.issues != null, "Issues have not been initialized");
checkArgument(component.equals(this.component),
- String.format("Only issues from component '%s' are available, but wanted component is '%s'.",
- this.component.getReportAttributes().getRef(), component.getReportAttributes().getRef()));
+ "Only issues from component '%s' are available, but wanted component is '%s'.",
+ this.component.getReportAttributes().getRef(), component.getReportAttributes().getRef());
return issues;
}
}
*/
package org.sonar.server.computation.task.projectanalysis.measure;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.FluentIterable.from;
-import static java.lang.String.format;
-import static java.util.Objects.requireNonNull;
-
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.SetMultimap;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.metric.Metric;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.SetMultimap;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.FluentIterable.from;
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
/**
* Map based implementation of MeasureRepository which supports only raw measures.
private static void checkValueTypeConsistency(Metric metric, Measure measure) {
checkArgument(
measure.getValueType() == Measure.ValueType.NO_VALUE || measure.getValueType() == metric.getType().getValueType(),
- format(
- "Measure's ValueType (%s) is not consistent with the Metric's ValueType (%s)",
- measure.getValueType(), metric.getType().getValueType()));
+ "Measure's ValueType (%s) is not consistent with the Metric's ValueType (%s)",
+ measure.getValueType(), metric.getType().getValueType());
}
@Override
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
}
private static Map<ScannerReport.Symbol, Integer> createIdsBySymbolMap(List<ScannerReport.Symbol> symbols) {
- Map<ScannerReport.Symbol, Integer> map = new HashMap<>(symbols.size());
+ Map<ScannerReport.Symbol, Integer> map = new IdentityHashMap<>(symbols.size());
int symbolId = 1;
for (ScannerReport.Symbol symbol : symbols) {
map.put(symbol, symbolId);
@Override
public void execute() {
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(CrawlerDepthLimit.LEAVES, ComponentVisitor.Order.PRE_ORDER) {
- @Override
- public void visitAny(Component component) {
- copy(component);
- }
- }).visit(treeRootHolder.getRoot());
+ try (DbSession session = dbClient.openSession(false)) {
+ CrawlerDepthLimit depthLimit = new CrawlerDepthLimit.Builder(Component.Type.MODULE)
+ .withViewsMaxDepth(Component.Type.PROJECT_VIEW);
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(depthLimit, ComponentVisitor.Order.PRE_ORDER) {
+ @Override
+ public void visitAny(Component component) {
+ copy(component, session);
+ }
+ }).visit(treeRootHolder.getRoot());
+ }
}
- private void copy(Component component) {
- for (CustomMeasureDto dto : loadCustomMeasures(component)) {
+ private void copy(Component component, DbSession session) {
+ for (CustomMeasureDto dto : loadCustomMeasures(component, session)) {
Metric metric = metricRepository.getById(dto.getMetricId());
// else metric is not found and an exception is raised
Measure measure = dtoToMeasure(dto, metric);
}
}
- private List<CustomMeasureDto> loadCustomMeasures(Component component) {
- try (DbSession session = dbClient.openSession(false)) {
- return dbClient.customMeasureDao().selectByComponentUuid(session, component.getUuid());
- }
+ private List<CustomMeasureDto> loadCustomMeasures(Component component, DbSession session) {
+ return dbClient.customMeasureDao().selectByComponentUuid(session, component.getUuid());
}
@VisibleForTesting
@Override
public void execute() {
- DbSession dbSession = dbClient.openSession(true);
- try {
+ try (DbSession dbSession = dbClient.openSession(true)) {
new DepthTraversalTypeAwareCrawler(new MeasureVisitor(dbSession)).visit(treeRootHolder.getRoot());
dbSession.commit();
- } finally {
- dbSession.close();
}
}
package org.sonar.server.computation.task.projectanalysis.component;
import java.util.Arrays;
+import java.util.Collections;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
.setUuid(UUID)
.setStatus(Status.UNAVAILABLE)
.setReportAttributes(ReportAttributes.newBuilder(1).build())
- .addChildren(child)
+ .addChildren(Collections.singletonList(child))
.build();
assertThat(componentImpl.getChildren()).hasSize(1);
import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries;
import static org.sonar.server.computation.task.projectanalysis.step.CustomMeasuresCopyStep.dtoToMeasure;
-
public class CustomMeasuresCopyStepTest {
private static final int PROJECT_REF = 1;
private static final int MODULE_REF = 11;
+ private static final int MODULE2_REF = 12;
private static final int SUB_MODULE_REF = 111;
private static final int DIR_REF = 1111;
private static final int FILE1_REF = 11111;
private static final String PROJECT_UUID = "PROJECT";
private static final String MODULE_UUID = "MODULE";
+ private static final String MODULE2_UUID = "MODULE2";
private static final String SUB_MODULE_UUID = "SUB_MODULE";
private static final String DIR_UUID = "DIR";
private static final String FILE1_UUID = "FILE1";
@Test
public void copy_custom_measures_on_report() {
- // File2 has no custom measure
insertCustomMeasure(FILE1_UUID, FLOAT_METRIC, 3.14);
insertCustomMeasure(DIR_UUID, FLOAT_METRIC, 123d);
insertCustomMeasure(SUB_MODULE_UUID, STRING_METRIC, "sub-module");
insertCustomMeasure(MODULE_UUID, STRING_METRIC, "module");
insertCustomMeasure(PROJECT_UUID, STRING_METRIC, "project");
+ // Module2 has no custom measure
treeRootHolder.setRoot(
builder(PROJECT, PROJECT_REF).setUuid(PROJECT_UUID)
ReportComponent.builder(DIRECTORY, DIR_REF).setUuid(DIR_UUID)
.addChildren(
ReportComponent.builder(FILE, FILE1_REF).setUuid(FILE1_UUID).build(),
- ReportComponent.builder(FILE, FILE2_REF).setUuid(FILE2_UUID).build()
- )
- .build()
- )
- .build()
- )
- .build())
+ ReportComponent.builder(FILE, FILE2_REF).setUuid(FILE2_UUID).build())
+ .build())
+ .build())
+ .build(),
+ ReportComponent.builder(MODULE, MODULE2_REF).setUuid(MODULE2_UUID).build())
.build());
underTest.execute();
- assertRawMeasureValue(FILE1_REF, FLOAT_METRIC.getKey(), 3.1d);
+ assertNoRawMeasureValue(FILE1_REF);
assertNoRawMeasureValue(FILE2_REF);
- assertRawMeasureValue(DIR_REF, FLOAT_METRIC.getKey(), 123d);
+ assertNoRawMeasureValue(DIR_REF);
assertRawMeasureValue(SUB_MODULE_REF, STRING_METRIC.getKey(), "sub-module");
assertRawMeasureValue(MODULE_REF, STRING_METRIC.getKey(), "module");
assertRawMeasureValue(PROJECT_REF, STRING_METRIC.getKey(), "project");
+ assertNoRawMeasureValue(MODULE2_REF);
+
}
@Test
ViewsComponent.builder(VIEW, VIEW_REF).setUuid("VIEW")
.addChildren(
ViewsComponent.builder(SUBVIEW, SUBVIEW_REF).setUuid("SUBVIEW").build(),
- ViewsComponent.builder(PROJECT_VIEW, PROJECT_VIEW_REF).setUuid("PROJECT_VIEW").build()
- )
+ ViewsComponent.builder(PROJECT_VIEW, PROJECT_VIEW_REF).setUuid("PROJECT_VIEW").build())
.build());
underTest.execute();
import org.sonar.api.utils.Duration;
import org.sonar.core.issue.tracking.Trackable;
-import static java.lang.String.format;
import static org.sonar.api.utils.DateUtils.truncateToSeconds;
public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.Issue {
}
public DefaultIssue setLine(@Nullable Integer l) {
- Preconditions.checkArgument(l == null || l > 0, format("Line must be null or greater than zero (got %d)", l));
+ Preconditions.checkArgument(l == null || l > 0, "Line must be null or greater than zero (got %d)", l);
this.line = l;
return this;
}
}
public DefaultIssue setGap(@Nullable Double d) {
- Preconditions.checkArgument(d == null || d >= 0, format("Gap must be greater than or equal 0 (got %s)", d));
+ Preconditions.checkArgument(d == null || d >= 0, "Gap must be greater than or equal 0 (got %s)", d);
this.gap = d;
return this;
}
*/
public RangeDistributionBuilder add(String data) {
Map<Double, Double> map = KeyValueFormat.parse(data, KeyValueFormat.newDoubleConverter(), KeyValueFormat.newDoubleConverter());
- Number[] limits = map.keySet().toArray(new Number[map.size()]);
if (bottomLimits == null) {
+ Number[] limits = map.keySet().toArray(new Number[map.size()]);
init(limits);
} else if (!areSameLimits(bottomLimits, map.keySet())) {
}
private void changeDoublesToInts() {
- boolean onlyInts = true;
for (Number bottomLimit : bottomLimits) {
if (NumberComparator.INSTANCE.compare(bottomLimit.intValue(), bottomLimit.doubleValue()) != 0) {
- onlyInts = false;
+ // it's not only ints
+ return;
}
}
- if (onlyInts) {
- for (int i = 0; i < bottomLimits.length; i++) {
- bottomLimits[i] = bottomLimits[i].intValue();
- }
+ for (int i = 0; i < bottomLimits.length; i++) {
+ bottomLimits[i] = bottomLimits[i].intValue();
}
}
@Override
public int compare(Number n1, Number n2) {
- return ((Double) n1.doubleValue()).compareTo(n2.doubleValue());
+ return Double.compare(n1.doubleValue(), n2.doubleValue());
}
}
.setProjectDir(baseDir);
BuildResult result = orchestrator.executeBuild(scanner);
- perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 8950);
+ perfRule.assertDurationAround(MavenLogs.extractTotalTime(result.getLogs()), 8200);
// Second execution with a property on server side
orchestrator.getServer().newHttpCall("/api/settings/set")