//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

= Jetty Jspc Maven Plugin

This plugin will pre-compile your JSP and works in conjunction with the Maven war plugin to put them inside an assembled war.

[[jspc-config]]
== Configuration

Here's the basic setup required to put the JSPC plugin into your build for the Jakarta EE {ee-current} environment:

[,xml,subs=attributes+]
----
<plugin>
  <groupId>org.eclipse.jetty.{ee-current}</groupId>
   <artifactId>jetty-{ee-current}-jspc-maven-plugin</artifactId>
   <version>{jetty-version}</version>
   <executions>
     <execution>
       <id>jspc</id>
       <goals>
         <goal>jspc</goal>
       </goals>
       <configuration>
       </configuration>
     </execution>
   </executions>
 </plugin>
----

The configurable parameters are as follows:

webXmlFragment::
Default value: `${project.basedir}/target/webfrag.xml`
+
File into which to generate the servlet declarations.
Will be merged with an existing `web.xml`.
webAppSourceDirectory::
Default value: `${project.basedir}/src/main/webapp`
+
Root of resources directory where jsps, tags etc are located.
webXml::
Default value: `${project.basedir}/src/main/webapp/WEB-INF/web.xml`
+
The web.xml file to use to merge with the generated fragments.
includes::
Default value: `+**/*.jsp, **/*.jspx+`
+
The comma separated list of patterns for file extensions to be processed.
excludes::
Default value: `+**/.svn/**+`
+
The comma separated list of patterns for file extensions to be skipped.
classesDirectory::
Default value: `${project.build.outputDirectory}`
+
Location of classes for the webapp.
generatedClasses::
Default value: `${project.build.outputDirectory}`
+
Location to put the generated classes for the jsps.
insertionMarker::
Default value: _none_
+
A marker string in the src `web.xml` file which indicates where to merge in the generated web.xml fragment.
Note that the marker string will NOT be preserved during the insertion.
Can be left blank, in which case the generated fragment is inserted just before the line containing `</web-app>`.
useProvidedScope::
Default value: false
+
If true, jars of dependencies marked with <scope>provided</scope> will be placed on the compilation classpath.
mergeFragment::
Default value: true
+
Whether or not to merge the generated fragment file with the source web.xml.
The merged file will go into the same directory as the webXmlFragment.
keepSources::
Default value: false
+
If true, the generated .java files are not deleted at the end of processing.
scanAllDirectories::
Default value: true
+
Determines if dirs on the classpath should be scanned as well as jars.
If true, this allows scanning for tlds of dependent projects that
are in the reactor as unassembled jars.
scanManifest::
Default value: true
+
Determines if the manifest of JAR files found on the classpath should be scanned.
sourceVersion::
Java version of jsp source files.
The default value depends on the version of the `jetty-{ee-current}-jspc-maven-plugin`.

targetVersion::
Java version of class files generated from jsps.
The default value depends on the version of the `jetty-{ee-current}-jspc-maven-plugin`.

tldJarNamePatterns::
Default value: `+.*taglibs[^/]*\.jar|.*jstl[^/]*\.jar$+`
+
Patterns of jars on the 'system' (ie container) path that contain tlds.
Use | to separate each pattern.
jspc::
Default value: the `org.apache.jasper.JspC` instance being configured.
+
The JspC class actually performs the pre-compilation.
All setters on the JspC class are available.

Taking all the default settings, here's how to configure the war plugin to use the generated `web.xml` that includes all of the jsp servlet declarations:

[,xml]
----
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-war-plugin</artifactId>
  <configuration>
    <webXml>${project.basedir}/target/web.xml</webXml>
  </configuration>
</plugin>
----

[[jspc-production-precompile]]
== Precompiling only for Production Build

As compiling jsps is usually done during preparation for a production release and not usually done during development, it is more convenient to put the plugin setup inside a <profile> which which can be deliberately invoked during prep for production.

For example, the following profile will only be invoked if the flag `-Dprod` is present on the run line:

[,xml,subs=attributes+]
----
<profiles>
  <profile>
    <id>prod</id>
    <activation>
      <property><name>prod</name></property>
    </activation>
    <build>
    <plugins>
      <plugin>
        <groupId>org.eclipse.jetty.{ee-current}</groupId>
        <artifactId>jetty-{ee-current}-jspc-maven-plugin</artifactId>
        <version>{jetty-version}</version>
        <!-- put your configuration in here -->
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <!-- put your configuration in here -->
      </plugin>
    </plugins>
    </build>
  </profile>
</profiles>
----

The following invocation would cause your code to be compiled, the jsps to be compiled, the <servlet> and <servlet-mapping>s inserted in the `web.xml` and your webapp assembled into a war:

----
$ mvn -Dprod package
----

[[jspc-overlay-precompile]]
== Precompiling Jsps with Overlaid Wars

Precompiling jsps with an overlaid war requires a bit more configuration.
This is because you need to separate the steps of unpacking the overlaid war and then repacking the final target war so the `jetty-{ee-current}-jspc-maven-plugin` has the opportunity to access the overlaid resources.

In the following example the overlaid war will provide the `web.xml` file but the jsps will be in `src/main/webapp` (i.e. part of the project that uses the overlay).
The overlaid war file will be unpacked, the jsps compiled and their servlet definitions merged into the extracted `web.xml`, and everything packed into a war.

An example configuration of the war plugin that separates those phases into an unpack phase, and then a packing phase:

[,xml]
----
<plugin>
  <artifactId>maven-war-plugin</artifactId>
  <executions>
    <execution>
      <id>unpack</id>
      <goals><goal>exploded</goal></goals>
      <phase>generate-resources</phase>
      <configuration>
        <webappDirectory>target/foo</webappDirectory>
        <overlays>
          <overlay />
          <overlay>
            <groupId>org.eclipse.jetty.{ee-current}.demos</groupId>
            <artifactId>jetty-{ee-current}-demo-jetty-webapp</artifactId>
          </overlay>
        </overlays>
      </configuration>
    </execution>
    <execution>
      <id>pack</id>
      <goals><goal>war</goal></goals>
      <phase>package</phase>
      <configuration>
        <warSourceDirectory>target/foo</warSourceDirectory>
        <webXml>target/web.xml</webXml>
      </configuration>
    </execution>
  </executions>
</plugin>
----

Now you also need to configure the `jetty-{ee-current}-jspc-maven-plugin` so that it can use the web.xml that was extracted by the war unpacking and merge in the generated definitions of the servlets.
This is in `target/foo/WEB-INF/web.xml`.
Using the default settings, the `web.xml` merged with the jsp servlet definitions will be put into `target/web.xml`.

[,xml,subs=attributes+]
----
<plugin>
  <groupId>org.eclipse.jetty.{ee-current}</groupId>
   <artifactId>jetty-{ee-current}-jspc-maven-plugin</artifactId>
   <version>{jetty-version}</version>
   <executions>
     <execution>
       <id>jspc</id>
       <goals>
         <goal>jspc</goal>
       </goals>
       <configuration>
          <webXml>target/foo/WEB-INF/web.xml</webXml>
          <includes>**/*.foo</includes>
          <excludes>**/*.fff</excludes>
      </configuration>
    </execution>
  </executions>
</plugin>
----
