From a4c64ee69b330aca019eeea07f4cba2635382c49 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 23 Dec 2014 11:29:38 +0100 Subject: [PATCH] SONAR-5967 Instead of not displaying anymore the source files containing more than 3'000 lines, only the highlighting mechanism should be deactivated above this limit --- .../sonar/server/source/SourceService.java | 4 + .../server/source/index/SourceLineIndex.java | 8 ++ .../sonar/server/source/ws/ShowAction.java | 18 +++-- .../server/source/SourceServiceTest.java | 10 ++- .../source/index/SourceLineIndexTest.java | 13 ++++ .../server/source/ws/ShowActionTest.java | 73 ++++++++++++++++++- 6 files changed, 112 insertions(+), 14 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/SourceService.java b/server/sonar-server/src/main/java/org/sonar/server/source/SourceService.java index 4b4add00ce5..b65ebd98050 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/SourceService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/SourceService.java @@ -77,6 +77,10 @@ public class SourceService implements ServerComponent { return lines; } + public long countLines(String fileUuid){ + return sourceLineIndex.countLines(fileUuid); + } + @CheckForNull public String getScmAuthorData(String fileKey) { checkPermission(fileKey); diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndex.java b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndex.java index f3c84bb650c..4567a0f11ba 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineIndex.java @@ -74,4 +74,12 @@ public class SourceLineIndex implements ServerComponent { return lines; } + + public long countLines(String fileUuid) { + return esClient.prepareCount(SourceLineIndexDefinition.INDEX) + .setTypes(SourceLineIndexDefinition.TYPE) + .setQuery(QueryBuilders.boolQuery() + .must(QueryBuilders.termQuery(SourceLineIndexDefinition.FIELD_FILE_UUID, fileUuid))) + .get().getCount(); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java index 9fb60b42a2e..3ba39a90169 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/ws/ShowAction.java @@ -30,7 +30,6 @@ import org.sonar.api.web.UserRole; import org.sonar.core.component.ComponentDto; import org.sonar.core.persistence.DbSession; import org.sonar.server.db.DbClient; -import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.source.SourceService; import org.sonar.server.user.UserSession; @@ -79,7 +78,6 @@ public class ShowAction implements RequestHandler { @Override public void handle(Request request, Response response) { String fileKey = request.mandatoryParam("key"); - UserSession.get().checkComponentPermission(UserRole.CODEVIEWER, fileKey); int from = Math.max(request.mandatoryParamAsInt("from"), 1); int to = (Integer) ObjectUtils.defaultIfNull(request.paramAsInt("to"), Integer.MAX_VALUE); @@ -87,11 +85,18 @@ public class ShowAction implements RequestHandler { DbSession session = dbClient.openSession(false); try { ComponentDto componentDto = dbClient.componentDao().getByKey(session, fileKey); - List linesHtml = sourceService.getLinesAsHtml(componentDto.uuid(), from, to); - if (linesHtml == null) { - throw new NotFoundException("File '" + fileKey + "' does not exist"); - } + UserSession.get().checkComponentPermission(UserRole.CODEVIEWER, fileKey); + + long linesSize = sourceService.countLines(componentDto.uuid()); + int size = to - from; + boolean disableHighlighting = size > 3000 && linesSize > 3000 ; + List linesHtml; + if (!disableHighlighting) { + linesHtml = sourceService.getLinesAsHtml(componentDto.uuid(), from, to); + } else { + linesHtml = sourceService.getLinesAsTxt(componentDto.uuid(), from, to); + } JsonWriter json = response.newJsonWriter().beginObject(); writeSource(linesHtml, from, json); @@ -99,7 +104,6 @@ public class ShowAction implements RequestHandler { } finally { session.close(); } - } private void writeSource(List lines, int from, JsonWriter json) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java index aac22010b27..b7f5c2e58dc 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java @@ -43,10 +43,7 @@ import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Fail.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class SourceServiceTest { @@ -152,4 +149,9 @@ public class SourceServiceTest { assertThat(result).contains("line1", "line2"); } + @Test + public void count_lines() throws Exception { + service.countLines(COMPONENT_UUID); + verify(sourceLineIndex).countLines(COMPONENT_UUID); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexTest.java index ced283fc0bb..8f1873dba9a 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineIndexTest.java @@ -63,4 +63,17 @@ public class SourceLineIndexTest { public void should_reject_to_less_than_from() { index.getLines("polop", 2, 1); } + + @Test + public void count_lines() throws Exception { + es.putDocuments(SourceLineIndexDefinition.INDEX, SourceLineIndexDefinition.TYPE, + this.getClass(), + "file1_line1.json", + "file1_line2.json", + "file2_line1.json", + "file2_line2.json", + "file2_line3.json"); + assertThat(index.countLines("file1")).isEqualTo(2); + assertThat(index.countLines("file2")).isEqualTo(3); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java index c3471efa0bb..666d41691c5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/ws/ShowActionTest.java @@ -38,9 +38,7 @@ import org.sonar.server.ws.WsTester; import static com.google.common.collect.Lists.newArrayList; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class ShowActionTest { @@ -76,6 +74,7 @@ public class ShowActionTest { String fileKey = "src/Foo.java"; MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(6L); when(sourceService.getLinesAsHtml(eq(file.uuid()), anyInt(), anyInt())).thenReturn(newArrayList( "/*", " * Header", @@ -94,6 +93,7 @@ public class ShowActionTest { String fileKey = "src/Foo.java"; MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(6L); when(sourceService.getLinesAsHtml(file.uuid(), 3, 5)).thenReturn(newArrayList( " */", "", @@ -112,6 +112,7 @@ public class ShowActionTest { String fileKey = "src/Foo.java"; MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(6L); when(sourceService.getLinesAsHtml(file.uuid(), 1, 5)).thenReturn(newArrayList( " */", "", @@ -126,6 +127,72 @@ public class ShowActionTest { verify(sourceService).getLinesAsHtml(file.uuid(), 1, 5); } + @Test + public void disable_highlighting_when_lines_greater_than_3000_without_from_and_to_params() throws Exception { + String fileKey = "src/Foo.java"; + MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); + when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(5000L); + WsTester.TestRequest request = tester + .newGetRequest("api/sources", "show") + .setParam("key", fileKey); + request.execute(); + + verify(sourceService).getLinesAsTxt(eq(file.uuid()), anyInt(), anyInt()); + verify(sourceService, never()).getLinesAsHtml(eq(file.uuid()), anyInt(), anyInt()); + } + + @Test + public void disable_highlighting_when_lines_greater_than_3000_with_from_and_to_params() throws Exception { + String fileKey = "src/Foo.java"; + MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); + when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(5000L); + WsTester.TestRequest request = tester + .newGetRequest("api/sources", "show") + .setParam("key", fileKey) + .setParam("from", "1000") + .setParam("to", "5000"); + request.execute(); + + verify(sourceService).getLinesAsTxt(eq(file.uuid()), anyInt(), anyInt()); + verify(sourceService, never()).getLinesAsHtml(eq(file.uuid()), anyInt(), anyInt()); + } + + @Test + public void not_disable_highlighting_when_lines_smaller_than_3000_but_to_minus_to_greater_than_3000() throws Exception { + String fileKey = "src/Foo.java"; + MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); + when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(1000L); + WsTester.TestRequest request = tester + .newGetRequest("api/sources", "show") + .setParam("key", fileKey) + .setParam("from", "1000") + .setParam("to", "5000"); + request.execute(); + + verify(sourceService, never()).getLinesAsTxt(eq(file.uuid()), anyInt(), anyInt()); + verify(sourceService).getLinesAsHtml(eq(file.uuid()), anyInt(), anyInt()); + } + + @Test + public void not_disable_highlighting_when_lines_greater_than_3000_but_to_minus_to_smaller_than_3000() throws Exception { + String fileKey = "src/Foo.java"; + MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "polop", fileKey); + when(componentDao.getByKey(session, fileKey)).thenReturn(file); + when(sourceService.countLines(file.uuid())).thenReturn(5000L); + WsTester.TestRequest request = tester + .newGetRequest("api/sources", "show") + .setParam("key", fileKey) + .setParam("from", "1") + .setParam("to", "10"); + request.execute(); + + verify(sourceService, never()).getLinesAsTxt(eq(file.uuid()), anyInt(), anyInt()); + verify(sourceService).getLinesAsHtml(eq(file.uuid()), anyInt(), anyInt()); + } + @Test(expected = ForbiddenException.class) public void require_code_viewer() throws Exception { String fileKey = "src/Foo.java"; -- 2.39.5