import com.google.common.io.Resources;
import java.util.Date;
import java.util.Optional;
+import java.util.function.Supplier;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.protobuf.DbFileSources;
import org.sonar.server.component.ComponentFinder;
public void handle(Request request, Response response) {
try (DbSession dbSession = dbClient.openSession(false)) {
ComponentDto file = loadComponent(dbSession, request);
+ Supplier<Optional<Long>> periodDateSupplier = () -> dbClient.snapshotDao()
+ .selectLastAnalysisByComponentUuid(dbSession, file.projectUuid())
+ .map(SnapshotDto::getPeriodDate);
+
userSession.checkComponentPermission(UserRole.CODEVIEWER, file);
int from = request.mandatoryParamAsInt(PARAM_FROM);
int to = MoreObjects.firstNonNull(request.paramAsInt(PARAM_TO), Integer.MAX_VALUE);
Iterable<DbFileSources.Line> lines = checkFoundWithOptional(sourceService.getLines(dbSession, file.uuid(), from, to), "No source found for file '%s'", file.getDbKey());
try (JsonWriter json = response.newJsonWriter()) {
json.beginObject();
- writeSource(lines, json, isMemberOfOrganization(dbSession, file));
+ writeSource(lines, json, isMemberOfOrganization(dbSession, file), periodDateSupplier);
json.endObject();
}
}
return componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, UUID_AND_KEY);
}
- checkRequest(componentKey!=null, "The '%s' parameter is missing", PARAM_KEY);
+ checkRequest(componentKey != null, "The '%s' parameter is missing", PARAM_KEY);
return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, branch, pullRequest);
}
- private void writeSource(Iterable<DbFileSources.Line> lines, JsonWriter json, boolean filterScmAuthors) {
+ private void writeSource(Iterable<DbFileSources.Line> lines, JsonWriter json, boolean filterScmAuthors, Supplier<Optional<Long>> periodDateSupplier) {
+ Optional<Long> periodDate = null;
+
json.name("sources").beginArray();
for (DbFileSources.Line line : lines) {
json.beginObject()
json.prop("coveredConditions", coveredConditions.get());
}
json.prop("duplicated", line.getDuplicationCount() > 0);
- json.prop("isNew", line.getIsNewLine());
+ if (line.hasIsNewLine()) {
+ json.prop("isNew", line.getIsNewLine());
+ } else {
+ if (periodDate == null) {
+ periodDate = periodDateSupplier.get();
+ }
+ json.prop("isNew", periodDate.isPresent() && line.getScmDate() > periodDate.get());
+ }
json.endObject();
}
json.endArray();
import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.component.SnapshotDao;
+import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.protobuf.DbFileSources;
import org.sonar.db.source.FileSourceDto;
public UserSessionRule userSession = UserSessionRule.standalone();
private ComponentDao componentDao = new ComponentDao();
+ private SnapshotDao snapshotDao = new SnapshotDao();
private ComponentDto privateProject;
private OrganizationDto organization;
private WsTester wsTester;
.assertJson(getClass(), "display_deprecated_fields.json");
}
+ @Test
+ public void use_period_date_if_new_line_not_yet_available_in_db() throws Exception {
+ DbFileSources.Data.Builder dataBuilder = DbFileSources.Data.newBuilder();
+ dataBuilder.addLines(DbFileSources.Line.newBuilder().setLine(1).setScmDate(1000L).build());
+ dataBuilder.addLines(DbFileSources.Line.newBuilder().setLine(2).setScmDate(2000L).build());
+ // only this line should be considered as new
+ dataBuilder.addLines(DbFileSources.Line.newBuilder().setLine(3).setScmDate(3000L).build());
+ ComponentDto project = db.components().insertPrivateProject();
+ insertPeriod(project, 2000L);
+ ComponentDto file = insertFileWithData(dataBuilder.build(), project);
+ setUserWithValidPermission(file);
+
+ wsTester
+ .newGetRequest("api/sources", "lines")
+ .setParam("uuid", file.uuid())
+ .execute()
+ .assertJson(getClass(), "generated_isNew.json");
+ }
+
@Test
public void use_deprecated_overall_coverage_fields_if_exists() throws Exception {
DbFileSources.Data.Builder dataBuilder = DbFileSources.Data.newBuilder();
.setScmDate(1_500_000_000_00L)
.setSource("SOURCE_" + 1);
}
+
+ private void insertPeriod(ComponentDto componentDto, long date) {
+ SnapshotDto dto = new SnapshotDto();
+ dto.setUuid("uuid");
+ dto.setLast(true);
+ dto.setPeriodDate(date);
+ dto.setComponentUuid(componentDto.uuid());
+ snapshotDao.insert(db.getSession(), dto);
+ }
}