static Duplication newTextComponent(String componentDbKey, Integer from, Integer size) { return new Duplication(null, componentDbKey, from, size, false); }
@Override public int compare(@Nullable Block b1, @Nullable Block b2) { if (b1 == null || b2 == null) { return -1; } List<Duplication> duplications1 = b1.getDuplications(); List<Duplication> duplications2 = b2.getDuplications(); if (duplications1.isEmpty() || duplications2.isEmpty()) { return -1; } return duplications1.get(0).from().compareTo(duplications2.get(0).from()); } }
@Override public int compare(@Nullable Duplication d1, @Nullable Duplication d2) { if (d1 == null || d2 == null) { return -1; } ComponentDto file1 = d1.componentDto(); ComponentDto file2 = d2.componentDto(); if (file1 != null && file1.equals(file2)) { // if duplication on same file => order by starting line return d1.from().compareTo(d2.from()); } if (sameFile(file1) && !sameFile(file2)) { // the current resource must be displayed first return -1; } if (sameFile(file2) && !sameFile(file1)) { // the current resource must be displayed first return 1; } if (sameProject(file1) && !sameProject(file2)) { // if resource is in the same project, this it must be displayed first return -1; } if (sameProject(file2) && !sameProject(file1)) { // if resource is in the same project, this it must be displayed first return 1; } return d1.from().compareTo(d2.from()); }
@Test public void duplication_on_not_existing_file() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto file = db.components().insertComponent(newFileDto(project)); List<DuplicationsParser.Block> blocks = parser.parse(db.getSession(), file, null, null, format("<duplications>\n" + " <g>\n" + " <b s=\"20\" l=\"5\" r=\"%s\"/>\n" + " <b s=\"31\" l=\"5\" r=\"%s\"/>\n" + " </g>\n" + "</duplications>", file.getDbKey(), "not_existing")); assertThat(blocks).hasSize(1); List<Duplication> duplications = blocks.get(0).getDuplications(); assertThat(duplications).hasSize(2); // Duplications on removed file Duplication duplication1 = duplication(duplications, null); assertThat(duplication1.componentDto()).isNull(); assertThat(duplication1.from()).isEqualTo(31); assertThat(duplication1.size()).isEqualTo(5); Duplication duplication2 = duplication(duplications, file.getDbKey()); assertThat(duplication2.componentDto()).isEqualTo(file); assertThat(duplication2.from()).isEqualTo(20); assertThat(duplication2.size()).isEqualTo(5); }
private static Block.Builder toWsBlock(Duplication duplication, Map<String, Reference> refByComponentKey) { Block.Builder block = Block.newBuilder(); if (!duplication.removed()) { Reference ref = refByComponentKey.computeIfAbsent(duplication.componentDbKey(), k -> new Reference( Integer.toString(refByComponentKey.size() + 1), duplication.componentDto(), duplication.componentDbKey())); block.setRef(ref.getId()); } block.setFrom(duplication.from()); block.setSize(duplication.size()); return block; }
@Override public void handle(Request request, Response response) { try (DbSession dbSession = dbClient.openSession(false)) { ComponentDto component = loadComponent(dbSession, request); userSession.checkComponentPermission(UserRole.CODEVIEWER, component); String duplications = findDataFromComponent(dbSession, component); String branch = component.getBranch(); String pullRequest = component.getPullRequest(); List<DuplicationsParser.Block> blocks = parser.parse(dbSession, component, branch, pullRequest, duplications); writeProtobuf(responseBuilder.build(dbSession, blocks, branch, pullRequest), request, response); } }
private void writeFileRefs(DbSession session, Map<String, Reference> refByComponentKey, ShowResponse.Builder response, @Nullable String branch, @Nullable String pullRequest) { Map<String, ComponentDto> projectsByUuid = new HashMap<>(); Map<String, ComponentDto> parentModulesByUuid = new HashMap<>(); for (Map.Entry<String, Reference> entry : refByComponentKey.entrySet()) { Reference ref = entry.getValue(); ComponentDto file = ref.getDto(); if (file != null) { ComponentDto project = getProject(file.projectUuid(), projectsByUuid, session); ComponentDto parentModule = getParentProject(file.moduleUuid(), parentModulesByUuid, session); response.putFiles(ref.getId(), toWsFile(file, project, parentModule, branch, pullRequest)); } else { response.putFiles(ref.getId(), toWsFile(ref.getComponentKey(), branch, pullRequest)); } } }
private Duplication createDuplication(Map<String, ComponentDto> componentsByKey, @Nullable String branch, @Nullable String pullRequest, String from, String size, String componentDbKey, DbSession session) { String componentKey = convertToKey(componentDbKey); ComponentDto component; if (componentsByKey.containsKey(componentKey)) { component = componentsByKey.get(componentKey); } else { component = loadComponent(session, componentKey, branch, pullRequest); componentsByKey.put(componentKey, component); } if (component != null) { return Duplication.newComponent(component, Integer.valueOf(from), Integer.valueOf(size)); } else { //This can happen if the target was removed (cross-project duplications) return Duplication.newRemovedComponent(componentKey, Integer.valueOf(from), Integer.valueOf(size)); } }
ComponentDto file = db.components().insertComponent(newFileDto(project)); List<DuplicationsParser.Block> blocks = newArrayList(); blocks.add(new DuplicationsParser.Block(newArrayList( Duplication.newComponent(file, 57, 12), Duplication.newRemovedComponent("key", 73, 12)))); test(blocks, null, null, "{\n" + " \"duplications\": [\n" +
private static Duplications.Duplication.Builder toWsDuplication(DuplicationsParser.Block block, Map<String, Reference> refByComponentKey) { Duplications.Duplication.Builder wsDuplication = Duplications.Duplication.newBuilder(); block.getDuplications().stream() .map(duplication -> toWsBlock(duplication, refByComponentKey)) .forEach(wsDuplication::addBlocks); return wsDuplication; }
ComponentDto file2 = db.components().insertComponent(newFileDto(project)); List<DuplicationsParser.Block> blocks = newArrayList(); blocks.add(new DuplicationsParser.Block(newArrayList( Duplication.newComponent(file1, 57, 12), Duplication.newComponent(file2, 73, 12)))); test(blocks, null, null, "{\n" + " \"duplications\": [\n" +
@Test public void get_duplications_by_file_key() throws Exception { TestRequest request = newBaseRequest(); verifyCallToFileWithDuplications(file -> request.setParam("key", file.getDbKey())); }
private static Duplication duplication(List<Duplication> duplications, @Nullable final String componentKey) { return Iterables.find(duplications, input -> input != null && (componentKey == null ? input.componentDto() == null : input.componentDto() != null && componentKey.equals(input.componentDto().getDbKey()))); }
@Override public void define(Context context) { NewController controller = context.createController("api/duplications") .setSince("4.4") .setDescription("Get duplication information for a project."); showAction.define(controller); controller.done(); } }
@Test public void fail_if_no_parameter_provided() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("Either 'uuid' or 'key' must be provided"); newBaseRequest().execute(); }
@Test public void write_nothing_when_no_data() { test(Collections.emptyList(), null, null, "{\"duplications\": [], \"files\": {}}"); }
@Test public void get_duplications_by_file_id() throws Exception { TestRequest request = newBaseRequest(); verifyCallToFileWithDuplications(file -> request.setParam("uuid", file.uuid())); }
static Duplication newRemovedComponent(String componentDbKey, Integer from, Integer size) { return new Duplication(null, componentDbKey, from, size, true); }
@Test public void fail_if_file_does_not_exist() { expectedException.expect(NotFoundException.class); newBaseRequest().setParam("key", "missing").execute(); }
static Duplication newComponent(ComponentDto componentDto, Integer from, Integer size) { return new Duplication(componentDto, componentDto.getDbKey(), from, size, false); }