]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5967 Instead of not displaying anymore the source files containing more than...
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 23 Dec 2014 14:02:32 +0000 (15:02 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 23 Dec 2014 14:02:32 +0000 (15:02 +0100)
server/sonar-server/src/main/java/org/sonar/server/source/DeprecatedSourceDecorator.java
server/sonar-server/src/main/java/org/sonar/server/source/HtmlSourceDecorator.java
server/sonar-server/src/main/java/org/sonar/server/source/SourceService.java
server/sonar-server/src/test/java/org/sonar/server/source/DeprecatedSourceDecoratorTest.java
server/sonar-server/src/test/java/org/sonar/server/source/HtmlSourceDecoratorTest.java
server/sonar-server/src/test/java/org/sonar/server/source/SourceServiceTest.java

index 9ad21b6d5440f3cd76da100da99a6fac8c5bc59c..81726f67a1a820bbb21394ebad3999d59d5289bc 100644 (file)
 package org.sonar.server.source;
 
 import com.google.common.base.Splitter;
-import org.apache.ibatis.session.SqlSession;
 import org.sonar.api.ServerComponent;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-import org.sonar.core.source.db.SnapshotSourceDao;
-import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.core.component.ComponentDto;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -42,40 +36,19 @@ import static com.google.common.collect.Lists.newArrayList;
  */
 public class DeprecatedSourceDecorator implements ServerComponent {
 
-  private final MyBatis mybatis;
-  private final ResourceDao resourceDao;
   private final CodeColorizers codeColorizers;
-  private final SnapshotSourceDao snapshotSourceDao;
 
-  public DeprecatedSourceDecorator(MyBatis mybatis, ResourceDao resourceDao, CodeColorizers codeColorizers, SnapshotSourceDao snapshotSourceDao) {
-    this.mybatis = mybatis;
-    this.resourceDao = resourceDao;
+  public DeprecatedSourceDecorator(CodeColorizers codeColorizers) {
     this.codeColorizers = codeColorizers;
-    this.snapshotSourceDao = snapshotSourceDao;
   }
 
   @CheckForNull
-  public List<String> getSourceAsHtml(String componentKey) {
-    return getSourceAsHtml(componentKey, null, null);
+  public List<String> getSourceAsHtml(ComponentDto component, String source) {
+    return getSourceAsHtml(component, source, null, null);
   }
 
-  @CheckForNull
-  public List<String> getSourceAsHtml(String componentKey, @Nullable Integer from, @Nullable Integer to) {
-    SqlSession session = mybatis.openSession(false);
-    try {
-      ResourceDto component = resourceDao.getResource(ResourceQuery.create().setKey(componentKey), session);
-      if (component == null) {
-        throw new NotFoundException("The component '" + componentKey + "' does not exists.");
-      }
-      String source = snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session);
-      if (source != null) {
-        return splitSourceByLine(source, component.getLanguage(), from, to);
-      } else {
-        return null;
-      }
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
+  public List<String> getSourceAsHtml(ComponentDto component, String source, @Nullable Integer from, @Nullable Integer to) {
+    return splitSourceByLine(source, component.language(), from, to);
   }
 
   private List<String> splitSourceByLine(String source, String language, @Nullable Integer from, @Nullable Integer to) {
index cfde941a2195652992df9aa2d88717fe2c5acd9a..68826b5c7e657df1b462a7bed421f003c011e652 100644 (file)
@@ -23,7 +23,6 @@ import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import org.apache.ibatis.session.SqlSession;
 import org.sonar.api.ServerComponent;
-import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.source.SnapshotDataTypes;
 import org.sonar.core.source.db.SnapshotDataDao;
 import org.sonar.core.source.db.SnapshotDataDto;
@@ -37,32 +36,26 @@ import java.util.List;
 
 public class HtmlSourceDecorator implements ServerComponent {
 
-  private final MyBatis mybatis;
-
   private final SnapshotSourceDao snapshotSourceDao;
   private final SnapshotDataDao snapshotDataDao;
 
-  public HtmlSourceDecorator(MyBatis mybatis, SnapshotSourceDao snapshotSourceDao, SnapshotDataDao snapshotDataDao) {
-    this.mybatis = mybatis;
+  public HtmlSourceDecorator(SnapshotSourceDao snapshotSourceDao, SnapshotDataDao snapshotDataDao) {
     this.snapshotSourceDao = snapshotSourceDao;
     this.snapshotDataDao = snapshotDataDao;
   }
 
   @CheckForNull
-  public List<String> getDecoratedSourceAsHtml(String componentKey, @Nullable Integer from, @Nullable Integer to) {
-    SqlSession session = mybatis.openSession(false);
-    try {
-      Collection<SnapshotDataDto> snapshotDataEntries = snapshotDataDao.selectSnapshotDataByComponentKey(componentKey, highlightingDataTypes(), session);
-      if (!snapshotDataEntries.isEmpty()) {
-        String snapshotSource = snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session);
-        return decorate(snapshotSource, snapshotDataEntries, from, to);
-      }
-      return null;
-    } finally {
-      MyBatis.closeQuietly(session);
+  public List<String> getDecoratedSourceAsHtml(SqlSession session, String componentKey, String snapshotSource, @Nullable Integer from, @Nullable Integer to) {
+    Collection<SnapshotDataDto> snapshotDataEntries = snapshotDataDao.selectSnapshotDataByComponentKey(componentKey, highlightingDataTypes(), session);
+    if (!snapshotDataEntries.isEmpty()) {
+      return decorate(snapshotSource, snapshotDataEntries, from, to);
     }
+    return null;
   }
 
+  /**
+   * Only used on rails side to display source in issue viewer (display 10 lines, so no need to return only source code if more than 3000 lines)
+   */
   @CheckForNull
   public List<String> getDecoratedSourceAsHtml(long snapshotId) {
     Collection<SnapshotDataDto> snapshotDataEntries = snapshotDataDao.selectSnapshotData(snapshotId, highlightingDataTypes());
index 8e2733046fb8350e431ba6d82b9337bbe51ae231..ea8b7ad3c5072c30abeb50253913d7ec8f9a2b2c 100644 (file)
 
 package org.sonar.server.source;
 
+import com.google.common.base.Splitter;
 import org.sonar.api.ServerComponent;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
 import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.core.measure.db.MeasureKey;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.source.db.SnapshotSourceDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 
+import java.util.Collections;
 import java.util.List;
 
+import static com.google.common.collect.Lists.newArrayList;
+
 public class SourceService implements ServerComponent {
 
   private final DbClient dbClient;
+  private final SnapshotSourceDao snapshotSourceDao;
   private final HtmlSourceDecorator sourceDecorator;
 
   /**
@@ -45,8 +52,9 @@ public class SourceService implements ServerComponent {
    */
   private final DeprecatedSourceDecorator deprecatedSourceDecorator;
 
-  public SourceService(DbClient dbClient, HtmlSourceDecorator sourceDecorator, DeprecatedSourceDecorator deprecatedSourceDecorator) {
+  public SourceService(DbClient dbClient, SnapshotSourceDao snapshotSourceDao, HtmlSourceDecorator sourceDecorator, DeprecatedSourceDecorator deprecatedSourceDecorator) {
     this.dbClient = dbClient;
+    this.snapshotSourceDao = snapshotSourceDao;
     this.sourceDecorator = sourceDecorator;
     this.deprecatedSourceDecorator = deprecatedSourceDecorator;
   }
@@ -58,13 +66,26 @@ public class SourceService implements ServerComponent {
 
   @CheckForNull
   public List<String> getLinesAsHtml(String fileKey, @Nullable Integer from, @Nullable Integer to) {
-    checkPermission(fileKey);
-
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(fileKey, from, to);
-    if (decoratedSource != null) {
-      return decoratedSource;
+    DbSession session = dbClient.openSession(false);
+    try {
+      ComponentDto component = dbClient.componentDao().getByKey(session, fileKey);
+      checkPermission(fileKey);
+      String source = snapshotSourceDao.selectSnapshotSourceByComponentKey(fileKey, session);
+      if (source != null) {
+        if (sizeBiggerThan3000Lines(source)) {
+          return getLinesAsTxt(source);
+        }
+
+        List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(session, fileKey, source, from, to);
+        if (decoratedSource != null) {
+          return decoratedSource;
+        }
+        return deprecatedSourceDecorator.getSourceAsHtml(component, source, from, to);
+      }
+      return null;
+    } finally {
+      MyBatis.closeQuietly(session);
     }
-    return deprecatedSourceDecorator.getSourceAsHtml(fileKey, from, to);
   }
 
   @CheckForNull
@@ -97,4 +118,15 @@ public class SourceService implements ServerComponent {
     }
   }
 
+  private static boolean sizeBiggerThan3000Lines (String source){
+    return source.length() > 120000;
+  }
+
+  private static List<String> getLinesAsTxt(@Nullable String source) {
+    if (source != null) {
+      return newArrayList(Splitter.onPattern("\r?\n|\r").split(source));
+    }
+    return Collections.emptyList();
+  }
+
 }
index fb87aace956dc98b6ef68bfca393f1c71c0526fa..3ad39473cb39444360bb00e2a31cc7c759248bb8 100644 (file)
@@ -25,122 +25,67 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-import org.sonar.core.source.db.SnapshotSourceDao;
-import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.core.component.ComponentDto;
 
 import java.util.List;
 
 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.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class DeprecatedSourceDecoratorTest {
 
-  @Mock
-  MyBatis mybatis;
-
-  @Mock
-  DbSession session;
-
-  @Mock
-  ResourceDao resourceDao;
-
   @Mock
   CodeColorizers codeColorizers;
 
-  @Mock
-  SnapshotSourceDao snapshotSourceDao;
-
   DeprecatedSourceDecorator sourceDecorator;
 
   @Before
   public void setUp() throws Exception {
-    when(mybatis.openSession(false)).thenReturn(session);
-    sourceDecorator = new DeprecatedSourceDecorator(mybatis, resourceDao, codeColorizers, snapshotSourceDao);
+    sourceDecorator = new DeprecatedSourceDecorator(codeColorizers);
   }
 
   @Test
   public void get_source_as_html() throws Exception {
-    String componentKey = "org.sonar.sample:Sample";
     String source = "line 1\nline 2\nline 3\n";
     String htmlSource = "<span>line 1</span>\n<span>line 2</span>\n";
 
-    when(resourceDao.getResource(any(ResourceQuery.class), eq(session))).thenReturn(new ResourceDto().setKey(componentKey).setLanguage("java"));
-    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session)).thenReturn(source);
     when(codeColorizers.toHtml(source, "java")).thenReturn(htmlSource);
 
-    List<String> result = sourceDecorator.getSourceAsHtml(componentKey);
+    List<String> result = sourceDecorator.getSourceAsHtml(new ComponentDto().setLanguage("java"), source);
     assertThat(result).containsExactly("<span>line 1</span>", "<span>line 2</span>", "");
   }
 
-  @Test
-  public void return_null_if_no_source_code_on_component() throws Exception {
-    String componentKey = "org.sonar.sample:Sample";
-    when(resourceDao.getResource(any(ResourceQuery.class), eq(session))).thenReturn(new ResourceDto().setKey(componentKey).setLanguage("java"));
-    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session)).thenReturn(null);
-
-    assertThat(sourceDecorator.getSourceAsHtml(componentKey)).isNull();
-  }
-
-  @Test
-  public void fail_to_get_source_as_html_on_unknown_component() throws Exception {
-    String componentKey = "org.sonar.sample:Sample";
-    when(resourceDao.getResource(any(ResourceQuery.class), eq(session))).thenReturn(null);
-    try {
-      sourceDecorator.getSourceAsHtml(componentKey);
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(NotFoundException.class);
-    }
-  }
-
   @Test
   public void get_source_as_html_with_from_and_to_params() throws Exception {
-    String componentKey = "org.sonar.sample:Sample";
     String source = "line 1\nline 2\nline 3\n";
     String htmlSource = "<span>line 1</span>\n<span>line 2</span>\n<span>line 3</span>\n";
 
-    when(resourceDao.getResource(any(ResourceQuery.class), eq(session))).thenReturn(new ResourceDto().setKey(componentKey).setLanguage("java"));
-    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session)).thenReturn(source);
     when(codeColorizers.toHtml(source, "java")).thenReturn(htmlSource);
 
-    List<String> result = sourceDecorator.getSourceAsHtml(componentKey, 2, 3);
+    List<String> result = sourceDecorator.getSourceAsHtml(new ComponentDto().setLanguage("java"), source, 2, 3);
     assertThat(result).containsExactly("<span>line 2</span>", "<span>line 3</span>");
   }
 
   @Test
   public void get_source_as_html_with_from_param() throws Exception {
-    String componentKey = "org.sonar.sample:Sample";
     String source = "line 1\nline 2\nline 3\n";
     String htmlSource = "<span>line 1</span>\n<span>line 2</span>\n<span>line 3</span>\n";
 
-    when(resourceDao.getResource(any(ResourceQuery.class), eq(session))).thenReturn(new ResourceDto().setKey(componentKey).setLanguage("java"));
-    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session)).thenReturn(source);
     when(codeColorizers.toHtml(source, "java")).thenReturn(htmlSource);
 
-    List<String> result = sourceDecorator.getSourceAsHtml(componentKey, 2, null);
+    List<String> result = sourceDecorator.getSourceAsHtml(new ComponentDto().setLanguage("java"), source, 2, null);
     assertThat(result).containsExactly("<span>line 2</span>", "<span>line 3</span>", "");
   }
 
   @Test
   public void get_source_as_html_with_to_param() throws Exception {
-    String componentKey = "org.sonar.sample:Sample";
     String source = "line 1\nline 2\nline 3\n";
     String htmlSource = "<span>line 1</span>\n<span>line 2</span>\n<span>line 3</span>\n";
 
-    when(resourceDao.getResource(any(ResourceQuery.class), eq(session))).thenReturn(new ResourceDto().setKey(componentKey).setLanguage("java"));
-    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(componentKey, session)).thenReturn(source);
     when(codeColorizers.toHtml(source, "java")).thenReturn(htmlSource);
 
-    List<String> result = sourceDecorator.getSourceAsHtml(componentKey, null, 3);
+    List<String> result = sourceDecorator.getSourceAsHtml(new ComponentDto().setLanguage("java"), source, null, 3);
     assertThat(result).containsExactly("<span>line 1</span>", "<span>line 2</span>", "<span>line 3</span>");
   }
 }
index 7b29fcf0748f66533f9fb23bcdde007fb93860cf..ea279ded68a3ba226f3133173f32a68f1efd68d5 100644 (file)
@@ -22,10 +22,13 @@ package org.sonar.server.source;
 
 import com.google.common.collect.Lists;
 import org.apache.ibatis.session.SqlSession;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
 import org.sonar.core.persistence.AbstractDaoTestCase;
-import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.DbSession;
 import org.sonar.core.source.db.SnapshotDataDao;
 import org.sonar.core.source.db.SnapshotSourceDao;
 
@@ -34,8 +37,10 @@ import java.util.List;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.*;
 
+@RunWith(MockitoJUnitRunner.class)
 public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
+  DbSession session;
 
   HtmlSourceDecorator sourceDecorator;
 
@@ -43,9 +48,16 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
   public void setUpDatasets() {
     setupData("shared");
 
+    session = getMyBatis().openSession(false);
+
     SnapshotSourceDao snapshotSourceDao = new SnapshotSourceDao(getMyBatis());
     SnapshotDataDao snapshotDataDao = new SnapshotDataDao(getMyBatis());
-    sourceDecorator = new HtmlSourceDecorator(getMyBatis(), snapshotSourceDao, snapshotDataDao);
+    sourceDecorator = new HtmlSourceDecorator(snapshotSourceDao, snapshotDataDao);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    session.close();
   }
 
   @Test
@@ -64,7 +76,10 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void highlight_syntax_with_html_from_component() throws Exception {
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:Dispatcher", null, null);
+    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:Dispatcher",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n}",
+      null, null);
 
     assertThat(decoratedSource).containsExactly(
       "<span class=\"cppd\">/*</span>",
@@ -78,9 +93,16 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void highlight_syntax_with_html_from_component_on_given_lines() throws Exception {
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:Dispatcher", null, 2)).hasSize(2);
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:Dispatcher", 2, null)).hasSize(5);
-    assertThat(sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:Dispatcher", 1, 2)).hasSize(2);
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:Dispatcher",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n}",
+      null, 2)).hasSize(2);
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:Dispatcher",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n}", 2, null)).hasSize(5);
+    assertThat(sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:Dispatcher",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n}", 1, 2)).hasSize(2);
   }
 
   @Test
@@ -99,7 +121,9 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void mark_symbols_with_html_from_component() throws Exception {
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:VelocityManager", null, null);
+    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:VelocityManager",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n}", null, null);
 
     assertThat(decoratedSource).containsExactly(
       "/*",
@@ -132,7 +156,10 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
 
   @Test
   public void decorate_source_with_multiple_decoration_strategies_from_component() throws Exception {
-    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:DebuggingInterceptor", null, null);
+    List<String> decoratedSource = sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:DebuggingInterceptor",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n  public void foo() {\n  }\n  public void bar() {\n    foo();\n  }\n}",
+      null, null);
 
     assertThat(decoratedSource).containsExactly(
       "<span class=\"cppd\">/*</span>",
@@ -154,7 +181,7 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
     SnapshotSourceDao snapshotSourceDao = mock(SnapshotSourceDao.class);
     SnapshotDataDao snapshotDataDao = mock(SnapshotDataDao.class);
 
-    HtmlSourceDecorator sourceDecorator = new HtmlSourceDecorator(mock(MyBatis.class), snapshotSourceDao, snapshotDataDao);
+    HtmlSourceDecorator sourceDecorator = new HtmlSourceDecorator(snapshotSourceDao, snapshotDataDao);
 
     sourceDecorator.getDecoratedSourceAsHtml(14L);
 
@@ -167,9 +194,12 @@ public class HtmlSourceDecoratorTest extends AbstractDaoTestCase {
     SnapshotSourceDao snapshotSourceDao = mock(SnapshotSourceDao.class);
     SnapshotDataDao snapshotDataDao = mock(SnapshotDataDao.class);
 
-    HtmlSourceDecorator sourceDecorator = new HtmlSourceDecorator(mock(MyBatis.class), snapshotSourceDao, snapshotDataDao);
+    HtmlSourceDecorator sourceDecorator = new HtmlSourceDecorator(snapshotSourceDao, snapshotDataDao);
 
-    sourceDecorator.getDecoratedSourceAsHtml("org.apache.struts:struts:DebuggingInterceptor", null, null);
+    sourceDecorator.getDecoratedSourceAsHtml(session,
+      "org.apache.struts:struts:DebuggingInterceptor",
+      "/*\n * Header\n */\n\npublic class HelloWorld {\n  public void foo() {\n  }\n  public void bar() {\n    foo();\n  }\n}",
+      null, null);
 
     verify(snapshotDataDao, times(1)).selectSnapshotDataByComponentKey(eq("org.apache.struts:struts:DebuggingInterceptor"), eq(Lists.newArrayList("highlight_syntax", "symbol")),
       any(SqlSession.class));
index 27131efe1411fbba6c463ebb8f695588ca23f960..9a329004a1a35622c05260b791007dd48b3ece7d 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.sonar.server.source;
 
+import com.google.common.base.Strings;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -27,13 +28,18 @@ import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
 import org.sonar.core.measure.db.MeasureKey;
 import org.sonar.core.persistence.DbSession;
+import org.sonar.core.source.db.SnapshotSourceDao;
+import org.sonar.server.component.persistence.ComponentDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.measure.persistence.MeasureDao;
 import org.sonar.server.user.MockUserSession;
 
+import java.util.List;
+
 import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.assertions.Fail.fail;
 import static org.mockito.Mockito.*;
@@ -50,9 +56,19 @@ public class SourceServiceTest {
   @Mock
   DeprecatedSourceDecorator deprecatedSourceDecorator;
 
+  @Mock
+  SnapshotSourceDao snapshotSourceDao;
+
   @Mock
   MeasureDao measureDao;
 
+  @Mock
+  ComponentDao componentDao;
+
+  ComponentDto componentDto;
+
+  String source = "public class HelloWorld";
+
   static final String PROJECT_KEY = "org.sonar.sample";
   static final String COMPONENT_KEY = "org.sonar.sample:Sample";
 
@@ -63,35 +79,41 @@ public class SourceServiceTest {
     DbClient dbClient = mock(DbClient.class);
     when(dbClient.openSession(false)).thenReturn(session);
     when(dbClient.measureDao()).thenReturn(measureDao);
-    service = new SourceService(dbClient, sourceDecorator, deprecatedSourceDecorator);
+    when(dbClient.componentDao()).thenReturn(componentDao);
+    componentDto = new ComponentDto().setKey(COMPONENT_KEY).setId(1L);
+    when(componentDao.getByKey(session , COMPONENT_KEY)).thenReturn(componentDto);
+    service = new SourceService(dbClient, snapshotSourceDao, sourceDecorator, deprecatedSourceDecorator);
   }
 
   @Test
   public void get_lines() throws Exception {
     MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
+    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(COMPONENT_KEY, session)).thenReturn(source);
 
     service.getLinesAsHtml(COMPONENT_KEY);
 
-    verify(sourceDecorator).getDecoratedSourceAsHtml(COMPONENT_KEY, null, null);
+    verify(sourceDecorator).getDecoratedSourceAsHtml(session, COMPONENT_KEY, source, null, null);
   }
 
   @Test
   public void get_block_of_lines() throws Exception {
     MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
+    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(COMPONENT_KEY, session)).thenReturn(source);
 
     service.getLinesAsHtml(COMPONENT_KEY, 1, 2);
 
-    verify(sourceDecorator).getDecoratedSourceAsHtml(COMPONENT_KEY, 1, 2);
+    verify(sourceDecorator).getDecoratedSourceAsHtml(session, COMPONENT_KEY, source, 1, 2);
   }
 
   @Test
   public void get_lines_from_deprecated_source_decorator_when_no_data_from_new_decorator() throws Exception {
     MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
-    when(sourceDecorator.getDecoratedSourceAsHtml(eq(COMPONENT_KEY), anyInt(), anyInt())).thenReturn(null);
+    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(COMPONENT_KEY, session)).thenReturn(source);
+    when(sourceDecorator.getDecoratedSourceAsHtml(eq(session), eq(COMPONENT_KEY), eq(source), anyInt(), anyInt())).thenReturn(null);
 
     service.getLinesAsHtml(COMPONENT_KEY, 1, 2);
 
-    verify(deprecatedSourceDecorator).getSourceAsHtml(COMPONENT_KEY, 1, 2);
+    verify(deprecatedSourceDecorator).getSourceAsHtml(componentDto, source, 1, 2);
   }
 
   @Test
@@ -133,4 +155,28 @@ public class SourceServiceTest {
     assertThat(service.getScmDateData(COMPONENT_KEY)).isNull();
   }
 
+  @Test
+  public void return_null_if_no_source() throws Exception {
+    MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
+    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(COMPONENT_KEY, session)).thenReturn(null);
+
+    assertThat(service.getLinesAsHtml(COMPONENT_KEY, 1, 2)).isNull();
+
+    verifyZeroInteractions(sourceDecorator);
+    verifyZeroInteractions(deprecatedSourceDecorator);
+  }
+
+  @Test
+  public void return_txt_when_source_is_too_big() throws Exception {
+    MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, PROJECT_KEY, COMPONENT_KEY);
+
+    when(snapshotSourceDao.selectSnapshotSourceByComponentKey(COMPONENT_KEY, session)).thenReturn(Strings.repeat("a\n", 130000));
+
+    List<String> lines = service.getLinesAsHtml(COMPONENT_KEY);
+    assertThat(lines).isNotEmpty();
+    assertThat(lines.size()).isGreaterThan(3000);
+
+    verifyZeroInteractions(sourceDecorator);
+    verifyZeroInteractions(deprecatedSourceDecorator);
+  }
 }