Search in sources :

Example 1 with GeneratedFile

use of org.sonar.java.model.GeneratedFile in project sonar-java by SonarSource.

the class JavaSensorTest method should_invoke_visitors_on_generated_code.

@Test
void should_invoke_visitors_on_generated_code() throws Exception {
    Path base = tmp.newFolder().toPath();
    Path generatedFilePath = tmp.newFile("Generated.java").toPath();
    Files.write(generatedFilePath, "class Generated {}".getBytes());
    GeneratedFile generatedFile = new GeneratedFile(generatedFilePath);
    SensorContextTester context = SensorContextTester.create(base);
    context.fileSystem().setWorkDir(tmp.newFolder().toPath());
    SonarComponents sonarComponents = createSonarComponentsMock(context);
    JavaFileScanner javaFileScanner = mock(JavaFileScanner.class);
    JspCodeScanner testCodeVisitor = mock(JspCodeScanner.class);
    when(sonarComponents.jspChecks()).thenReturn(Collections.singletonList(testCodeVisitor));
    when(sonarComponents.mainChecks()).thenReturn(Collections.singletonList(javaFileScanner));
    Jasper jasper = mock(Jasper.class);
    when(jasper.generateFiles(any(), any())).thenReturn(asList(generatedFile));
    JavaSensor jss = new JavaSensor(sonarComponents, context.fileSystem(), mock(JavaResourceLocator.class), new MapSettings().asConfig(), mock(NoSonarFilter.class), null, jasper);
    jss.execute(context);
    ArgumentCaptor<JavaFileScannerContext> scannerContext = ArgumentCaptor.forClass(JavaFileScannerContext.class);
    verify(testCodeVisitor, times(1)).scanFile(scannerContext.capture());
    assertThat(scannerContext.getValue().getInputFile()).isSameAs(generatedFile);
    // normal visitors are not invoked on generated files
    verify(javaFileScanner, never()).scanFile(any());
}
Also used : Path(java.nio.file.Path) SensorContextTester(org.sonar.api.batch.sensor.internal.SensorContextTester) NoSonarFilter(org.sonar.api.issue.NoSonarFilter) JavaFileScanner(org.sonar.plugins.java.api.JavaFileScanner) DefaultJavaResourceLocator(org.sonar.java.DefaultJavaResourceLocator) JavaResourceLocator(org.sonar.plugins.java.api.JavaResourceLocator) GeneratedFile(org.sonar.java.model.GeneratedFile) SonarComponents(org.sonar.java.SonarComponents) Jasper(org.sonar.java.jsp.Jasper) MapSettings(org.sonar.api.config.internal.MapSettings) JavaFileScannerContext(org.sonar.plugins.java.api.JavaFileScannerContext) Test(org.junit.jupiter.api.Test) ClasspathForTest(org.sonar.java.classpath.ClasspathForTest)

Example 2 with GeneratedFile

use of org.sonar.java.model.GeneratedFile in project sonar-java by SonarSource.

the class Jasper method generateFiles.

public Collection<GeneratedFile> generateFiles(SensorContext sensorContext, List<File> javaClasspath) {
    List<String> sonarExclusions = Arrays.asList(sensorContext.config().getStringArray(SONAR_EXCLUSIONS_PROPERTY));
    if (isAllJavaJspExcluded(sonarExclusions)) {
        return Collections.emptyList();
    }
    Predicate<String> javaExclusionFilter = createExclusionFilter(sonarExclusions);
    List<InputFile> jspFiles = jspFiles(sensorContext.fileSystem());
    LOG.debug("Found {} JSP files.", jspFiles.size());
    if (jspFiles.isEmpty()) {
        return Collections.emptyList();
    }
    Path uriRoot = findWebInfParentDirectory(sensorContext.fileSystem()).orElse(sensorContext.fileSystem().baseDir().getAbsoluteFile().toPath());
    LOG.debug("Context root set to {}", uriRoot);
    Path outputDir = outputDir(sensorContext);
    // Jasper internally calls Thread#getContextClassLoader to instantiate some classes. ContextClassLoader is set by scanner
    // and doesn't contain plugin jar, so we need to configure ContextClassLoader with the class loader of the plugin to be able
    // to run Jasper. Original classloader is restored in finally.
    ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
    try {
        ClassLoader classLoader = initClassLoader(javaClasspath);
        Thread.currentThread().setContextClassLoader(classLoader);
        JspFactory.setDefaultFactory(new JspFactoryImpl());
        JspCServletContext servletContext = new ServletContext(uriRoot.toUri().toURL(), classLoader);
        JasperOptions options = getJasperOptions(outputDir, servletContext);
        JspRuntimeContext runtimeContext = new JspRuntimeContext(servletContext, options);
        boolean errorTranspiling = false;
        Map<Path, GeneratedFile> generatedJavaFiles = new HashMap<>();
        for (InputFile jsp : jspFiles) {
            try {
                transpileJsp(jsp.path(), uriRoot, classLoader, servletContext, options, runtimeContext, javaExclusionFilter).ifPresent(generatedFile -> generatedJavaFiles.put(generatedFile, new GeneratedFile(generatedFile)));
            } catch (Exception | LinkageError e) {
                errorTranspiling = true;
                StringWriter w = new StringWriter();
                e.printStackTrace(new PrintWriter(w));
                LOG.debug("Error transpiling {}. Error:\n{}", jsp, w.toString());
            }
        }
        if (errorTranspiling) {
            LOG.warn("Some JSP pages failed to transpile. Enable debug log for details.");
        }
        runtimeContext.getSmaps().values().forEach(smap -> processSourceMap(uriRoot, generatedJavaFiles, smap, sensorContext.fileSystem()));
        return generatedJavaFiles.values();
    } catch (Exception e) {
        LOG.warn("Failed to transpile JSP files.", e);
        return Collections.emptyList();
    } finally {
        Thread.currentThread().setContextClassLoader(originalClassLoader);
    }
}
Also used : Path(java.nio.file.Path) HashMap(java.util.HashMap) JspCServletContext(org.apache.jasper.servlet.JspCServletContext) GeneratedFile(org.sonar.java.model.GeneratedFile) JasperException(org.apache.jasper.JasperException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) InputFile(org.sonar.api.batch.fs.InputFile) StringWriter(java.io.StringWriter) JspRuntimeContext(org.apache.jasper.compiler.JspRuntimeContext) JspFactoryImpl(org.apache.jasper.runtime.JspFactoryImpl) URLClassLoader(java.net.URLClassLoader) JspCServletContext(org.apache.jasper.servlet.JspCServletContext) PrintWriter(java.io.PrintWriter)

Example 3 with GeneratedFile

use of org.sonar.java.model.GeneratedFile in project sonar-java by SonarSource.

the class JasperTest method test_exception_handling.

@Test
void test_exception_handling() throws Exception {
    SensorContextTester ctx = jspContext("<%=");
    Collection<GeneratedFile> inputFiles = new Jasper().generateFiles(ctx, emptyList());
    assertThat(inputFiles).isEmpty();
    assertThat(logTester.logs(LoggerLevel.DEBUG)).matches(logs -> logs.stream().anyMatch(line -> line.startsWith("Error transpiling src/main/webapp/WEB-INF/jsp/test.jsp.")));
    assertThat(logTester.logs(LoggerLevel.WARN)).contains("Some JSP pages failed to transpile. Enable debug log for details.");
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BeforeEach(org.junit.jupiter.api.BeforeEach) InputFile(org.sonar.api.batch.fs.InputFile) GeneratedFile(org.sonar.java.model.GeneratedFile) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) MapSettings(org.sonar.api.config.internal.MapSettings) Mockito.spy(org.mockito.Mockito.spy) DisabledOnOs(org.junit.jupiter.api.condition.DisabledOnOs) Collections.singletonList(java.util.Collections.singletonList) Mockito.doThrow(org.mockito.Mockito.doThrow) SensorContextTester(org.sonar.api.batch.sensor.internal.SensorContextTester) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) RegisterExtension(org.junit.jupiter.api.extension.RegisterExtension) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) LogTesterJUnit5(org.sonar.api.utils.log.LogTesterJUnit5) Path(java.nio.file.Path) WINDOWS(org.junit.jupiter.api.condition.OS.WINDOWS) Files(java.nio.file.Files) Predicate(java.util.function.Predicate) Collections.emptyList(java.util.Collections.emptyList) Collection(java.util.Collection) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) SensorContext(org.sonar.api.batch.sensor.SensorContext) File(java.io.File) StandardCharsets(java.nio.charset.StandardCharsets) TestInputFileBuilder(org.sonar.api.batch.fs.internal.TestInputFileBuilder) Test(org.junit.jupiter.api.Test) List(java.util.List) AfterEach(org.junit.jupiter.api.AfterEach) Paths(java.nio.file.Paths) TempDir(org.junit.jupiter.api.io.TempDir) PathUtils(org.apache.commons.io.file.PathUtils) LoggerLevel(org.sonar.api.utils.log.LoggerLevel) SensorContextTester(org.sonar.api.batch.sensor.internal.SensorContextTester) GeneratedFile(org.sonar.java.model.GeneratedFile) Test(org.junit.jupiter.api.Test)

Example 4 with GeneratedFile

use of org.sonar.java.model.GeneratedFile in project sonar-java by SonarSource.

the class JasperTest method test_empty.

@Test
void test_empty() throws Exception {
    SensorContextTester ctx = SensorContextTester.create(tempFolder);
    ctx.fileSystem().setWorkDir(workDir);
    Collection<GeneratedFile> generatedFiles = new Jasper().generateFiles(ctx, emptyList());
    assertThat(generatedFiles).isEmpty();
    assertThat(logTester.logs()).containsOnly("Found 0 JSP files.");
}
Also used : SensorContextTester(org.sonar.api.batch.sensor.internal.SensorContextTester) GeneratedFile(org.sonar.java.model.GeneratedFile) Test(org.junit.jupiter.api.Test)

Example 5 with GeneratedFile

use of org.sonar.java.model.GeneratedFile in project sonar-java by SonarSource.

the class JasperTest method test_compilation.

@Test
void test_compilation() throws Exception {
    SensorContextTester ctx = jspContext(JSP_SOURCE);
    Collection<GeneratedFile> generatedFiles = new Jasper().generateFiles(ctx, emptyList());
    assertThat(generatedFiles).hasSize(1);
    InputFile generatedFile = generatedFiles.iterator().next();
    List<String> generatedCode = Files.readAllLines(generatedFile.path());
    assertThat(generatedCode).contains("      out.write(\"<html>\\n<body>\\n<h2>Hello World!</h2>\\n</body>\\n</html>\");");
}
Also used : SensorContextTester(org.sonar.api.batch.sensor.internal.SensorContextTester) GeneratedFile(org.sonar.java.model.GeneratedFile) InputFile(org.sonar.api.batch.fs.InputFile) DefaultInputFile(org.sonar.api.batch.fs.internal.DefaultInputFile) Test(org.junit.jupiter.api.Test)

Aggregations

GeneratedFile (org.sonar.java.model.GeneratedFile)18 Test (org.junit.jupiter.api.Test)15 SensorContextTester (org.sonar.api.batch.sensor.internal.SensorContextTester)15 Path (java.nio.file.Path)8 InputFile (org.sonar.api.batch.fs.InputFile)8 MapSettings (org.sonar.api.config.internal.MapSettings)8 DefaultInputFile (org.sonar.api.batch.fs.internal.DefaultInputFile)7 IOException (java.io.IOException)4 DisabledOnOs (org.junit.jupiter.api.condition.DisabledOnOs)4 SensorContext (org.sonar.api.batch.sensor.SensorContext)4 File (java.io.File)3 StandardCharsets (java.nio.charset.StandardCharsets)3 Files (java.nio.file.Files)3 Paths (java.nio.file.Paths)3 Arrays.asList (java.util.Arrays.asList)3 Collection (java.util.Collection)3 Collections.emptyList (java.util.Collections.emptyList)3 Collections.singletonList (java.util.Collections.singletonList)3 List (java.util.List)3 Map (java.util.Map)3