SLING-9816 - Lookup jsp includes from the class path if not found locally

* added support for scanning the project's dependencies when looking
for JSPs required by the project's source files
diff --git a/pom.xml b/pom.xml
index 2c1b925..47cd42e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>38</version>
+        <version>40</version>
         <relativePath />
     </parent>
 
@@ -40,13 +40,18 @@
         <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/sling-jspc-maven-plugin.git</developerConnection>
         <url>https://gitbox.apache.org/repos/asf?p=sling-jspc-maven-plugin.git</url>
       <tag>HEAD</tag>
-  </scm>
+    </scm>
 
     <properties>
         <maven.site.path>${project.artifactId}-archives/${project.artifactId}-LATEST</maven.site.path>
         <site.jira.version.id>12313225,12313347,12319479,12319561,12325751,12347153,12348438,12348556</site.jira.version.id>
+        <maven.version>3.5.0</maven.version>
     </properties>
 
+    <prerequisites>
+        <maven>${maven.version}</maven>
+    </prerequisites>
+
     <build>
         <plugins>
             <plugin>
@@ -71,6 +76,7 @@
                 <configuration>
                     <excludes>
                         <exclude>src/site/markdown/**</exclude>
+                        <exclude>src/test/resources/jspc-maven-plugin-it-includes/target/**</exclude>
                     </excludes>
                 </configuration>
             </plugin>
@@ -114,6 +120,38 @@
         </plugins>
     </reporting>
 
+    <!-- force maven-plugin-testing-harness to use newer plexus container (https://issues.apache.org/jira/browse/MPLUGINTESTING-53) -->
+    <dependencyManagement>
+        <dependencies>
+            <!-- maven -->
+            <dependency>
+                <groupId>org.apache.maven</groupId>
+                <artifactId>maven-core</artifactId>
+                <version>${maven.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.maven</groupId>
+                <artifactId>maven-compat</artifactId>
+                <version>${maven.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.maven</groupId>
+                <artifactId>maven-model</artifactId>
+                <version>${maven.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.maven</groupId>
+                <artifactId>maven-plugin-api</artifactId>
+                <version>${maven.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.maven</groupId>
+                <artifactId>maven-aether-provider</artifactId>
+                <version>${maven.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
     <dependencies>
 
         <dependency>
@@ -163,7 +201,14 @@
         <dependency>
             <groupId>org.apache.maven</groupId>
             <artifactId>maven-plugin-api</artifactId>
-            <version>3.5.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.maven</groupId>
@@ -188,5 +233,36 @@
             <version>3.5</version>
             <scope>provided</scope>
         </dependency>
+
+        <!-- Testing Dependencies -->
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-container-default</artifactId>
+            <version>1.6</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>3.5.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven.plugin-testing</groupId>
+            <artifactId>maven-plugin-testing-harness</artifactId>
+            <version>3.3.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+            <scope>test</scope>
+            <version>${maven.version}</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/main/java/org/apache/sling/maven/jspc/JspCIOProvider.java b/src/main/java/org/apache/sling/maven/jspc/JspCIOProvider.java
index 748d25c..b5b1768 100644
--- a/src/main/java/org/apache/sling/maven/jspc/JspCIOProvider.java
+++ b/src/main/java/org/apache/sling/maven/jspc/JspCIOProvider.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URL;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.sling.commons.classloader.ClassLoaderWriter;
@@ -55,8 +56,23 @@
     }
 
     @Override
-    public InputStream getInputStream(String fileName) throws FileNotFoundException, IOException {
-        return FileUtils.openInputStream(getFile(fileName));
+    public InputStream getInputStream(String fileName) throws IOException {
+        File file = getFile(fileName);
+        if (file.exists()) {
+            return FileUtils.openInputStream(getFile(fileName));
+        }
+        // coming from a jar; remove the leading slash
+        String jarEntryPath;
+        if (fileName.startsWith("/")) {
+            jarEntryPath = fileName.substring(1);
+        } else {
+            jarEntryPath = fileName;
+        }
+        URL url = loader.getResource(jarEntryPath);
+        if (url != null) {
+            return url.openStream();
+        }
+        throw new FileNotFoundException("Cannot find file " + fileName + ".");
     }
 
     @Override
@@ -93,4 +109,4 @@
     public ClassLoaderWriter getClassLoaderWriter() {
         return writer;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/apache/sling/maven/jspc/JspcMojo.java b/src/main/java/org/apache/sling/maven/jspc/JspcMojo.java
index 3624f21..e21dc94 100644
--- a/src/main/java/org/apache/sling/maven/jspc/JspcMojo.java
+++ b/src/main/java/org/apache/sling/maven/jspc/JspcMojo.java
@@ -405,7 +405,7 @@
         classPath.add(new File(targetDirectory).toURI().toURL());
 
         // add artifacts from project
-        Set<Artifact> artifacts = project.getDependencyArtifacts();
+        Set<Artifact> artifacts = project.getArtifacts();
         jspcCompileArtifacts = new ArrayList<Artifact>(artifacts.size());
         for (Artifact a: artifacts) {
             final String scope = a.getScope();
diff --git a/src/test/java/org/apache/sling/maven/jspc/JspcMojoTest.java b/src/test/java/org/apache/sling/maven/jspc/JspcMojoTest.java
new file mode 100644
index 0000000..f7b9d39
--- /dev/null
+++ b/src/test/java/org/apache/sling/maven/jspc/JspcMojoTest.java
@@ -0,0 +1,97 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements.  See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership.  The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License.  You may obtain a copy of the License at
+ ~
+ ~   http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied.  See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+package org.apache.sling.maven.jspc;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.artifact.repository.DefaultArtifactRepository;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+
+public class JspcMojoTest {
+
+    private static final String INCLUDES_PROJECT = "src/test/resources/jspc-maven-plugin-it-includes";
+    private static final String REPOSITORY = "src/test/resources/jspc-maven-plugin-it-includes/repo";
+
+    @Rule
+    public MojoRule mojoRule = new MojoRule();
+
+    private MavenProject mavenProject;
+    private JspcMojo jspcMojo;
+    private File baseDir;
+
+    @Before
+    public void before() throws Exception {
+        baseDir = new File(INCLUDES_PROJECT);
+        MavenExecutionRequest request = new DefaultMavenExecutionRequest();
+        request.setBaseDirectory(baseDir);
+        ProjectBuildingRequest configuration = request.getProjectBuildingRequest();
+        configuration.setResolveDependencies(true);
+        configuration.setLocalRepository(new DefaultArtifactRepository("project", "file://" + new File(REPOSITORY).getAbsolutePath(),
+                new DefaultRepositoryLayout()));
+        mavenProject = mojoRule.lookup(ProjectBuilder.class).build(new File(baseDir, "pom.xml"), configuration).getProject();
+        Assert.assertNotNull(mavenProject);
+        MavenSession session = mojoRule.newMavenSession(mavenProject);
+        MojoExecution execution = mojoRule.newMojoExecution("jspc");
+        jspcMojo = (JspcMojo) mojoRule.lookupConfiguredMojo(session, execution);
+    }
+
+    @After
+    public void after() {
+        FileUtils.deleteQuietly(new File(baseDir, "target"));
+    }
+
+    @Test
+    public void testIncludesFromClassPath() throws Exception {
+        jspcMojo.execute();
+        File generatedMain = new File(mavenProject.getBuild().getOutputDirectory() + File.separator + "main__002e__jsp.java");
+        assertTrue("Expected to find a generated main__002e__jsp.java file.", generatedMain.exists());
+        FileReader fileReader = new FileReader(generatedMain);
+        BufferedReader bufferedReader = new BufferedReader(fileReader);
+        Set<String> expectedContent = new HashSet<>(Arrays.asList("included-fs.jsp", "included-cp.jsp", "/libs/l1/l2/included-cp.jsp"));
+        String line = bufferedReader.readLine();
+        while (line != null) {
+            expectedContent.removeIf(line::contains);
+            line = bufferedReader.readLine();
+        }
+        assertTrue("Some files were not correctly included: " + expectedContent.toString(), expectedContent.isEmpty());
+    }
+
+}
diff --git a/src/test/resources/jspc-maven-plugin-it-includes/pom.xml b/src/test/resources/jspc-maven-plugin-it-includes/pom.xml
new file mode 100644
index 0000000..80831c4
--- /dev/null
+++ b/src/test/resources/jspc-maven-plugin-it-includes/pom.xml
@@ -0,0 +1,60 @@
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>jspc-maven-plugin-it-includes</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <name>HTL Maven Plugin IT - Generate Java Classes</name>
+
+    <repositories>
+        <repository>
+            <id>project</id>
+            <url>file://${project.basedir}/repo</url>
+        </repository>
+    </repositories>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>jspc-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>jspc</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>jspc-maven-plugin-it-includes-deps</artifactId>
+            <version>0.0.1</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/0.0.1/jspc-maven-plugin-it-includes-deps-0.0.1.jar b/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/0.0.1/jspc-maven-plugin-it-includes-deps-0.0.1.jar
new file mode 100644
index 0000000..d2d0907
--- /dev/null
+++ b/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/0.0.1/jspc-maven-plugin-it-includes-deps-0.0.1.jar
Binary files differ
diff --git a/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/0.0.1/jspc-maven-plugin-it-includes-deps-0.0.1.pom b/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/0.0.1/jspc-maven-plugin-it-includes-deps-0.0.1.pom
new file mode 100644
index 0000000..306213a
--- /dev/null
+++ b/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/0.0.1/jspc-maven-plugin-it-includes-deps-0.0.1.pom
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.sling</groupId>
+  <artifactId>jspc-maven-plugin-it-includes-deps</artifactId>
+  <version>0.0.1</version>
+  <description>POM was created from install:install-file</description>
+</project>
diff --git a/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/maven-metadata-local.xml b/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/maven-metadata-local.xml
new file mode 100644
index 0000000..f55fdd5
--- /dev/null
+++ b/src/test/resources/jspc-maven-plugin-it-includes/repo/org/apache/sling/jspc-maven-plugin-it-includes-deps/maven-metadata-local.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<metadata>
+  <groupId>org.apache.sling</groupId>
+  <artifactId>jspc-maven-plugin-it-includes-deps</artifactId>
+  <versioning>
+    <release>0.0.1</release>
+    <versions>
+      <version>0.0.1</version>
+    </versions>
+    <lastUpdated>20201014094724</lastUpdated>
+  </versioning>
+</metadata>
diff --git a/src/test/resources/jspc-maven-plugin-it-includes/src/main/scripts/included-fs.jsp b/src/test/resources/jspc-maven-plugin-it-includes/src/main/scripts/included-fs.jsp
new file mode 100644
index 0000000..07514cf
--- /dev/null
+++ b/src/test/resources/jspc-maven-plugin-it-includes/src/main/scripts/included-fs.jsp
@@ -0,0 +1,19 @@
+<%--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--%>
+included-fs.jsp
diff --git a/src/test/resources/jspc-maven-plugin-it-includes/src/main/scripts/main.jsp b/src/test/resources/jspc-maven-plugin-it-includes/src/main/scripts/main.jsp
new file mode 100644
index 0000000..3761afb
--- /dev/null
+++ b/src/test/resources/jspc-maven-plugin-it-includes/src/main/scripts/main.jsp
@@ -0,0 +1,21 @@
+<%--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--%>
+<%@include file="included-fs.jsp"%>
+<%@include file="included-cp.jsp"%>
+<%@include file="/libs/l1/l2/included-cp.jsp"%>