<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Yet Another UserAgent Analyzer
  ~ Copyright (C) 2013-2026 Niels Basjes
  ~
  ~ Licensed 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
  ~
  ~ https://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">
  <parent>
    <artifactId>yauaa-parent</artifactId>
    <groupId>nl.basjes.parse.useragent</groupId>
    <version>8.2.0</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <artifactId>yauaa-webapp</artifactId>
  <name>Yauaa : Web Servlet</name>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.release>21</maven.compiler.release>

    <main.class>nl.basjes.parse.useragent.servlet.ParseService</main.class>

    <!-- The default port on which to expose if you do "mvn docker:run" -->
    <yauaa.port>8080</yauaa.port>
  </properties>

  <dependencies>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j2.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>${spring-boot.version}</version>
    </dependency>

    <dependency>
      <groupId>jakarta.validation</groupId>
      <artifactId>jakarta.validation-api</artifactId>
      <version>3.1.1</version>
    </dependency>

    <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>${springdoc.version}</version>
      <exclusions>
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.yaml</groupId>
          <artifactId>snakeyaml</artifactId>
        </exclusion>
        <exclusion>
          <groupId>jakarta.validation</groupId>
          <artifactId>jakarta.validation-api</artifactId>
        </exclusion>
        <exclusion>
          <artifactId>commons-lang3</artifactId>
          <groupId>org.apache.commons</groupId>
        </exclusion>
        <exclusion>
          <groupId>org.apache.tomcat.embed</groupId>
          <artifactId>tomcat-embed-el</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-autoconfigure</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-jackson</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-web-server</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-webmvc</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.yaml</groupId>
      <artifactId>snakeyaml</artifactId>
      <version>${snakeyaml.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <version>${spring-boot.version}</version>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <!-- ================================================================================================ -->
    <!-- These 3 dependencies are excluded by all UDFs because of dependency/shading/ relocating problems -->
    <!-- But they do need them for the compilation and testing ... -->
    <!-- Documentation of the used shading construct: https://yauaa.basjes.nl/NOTES-shading-dependencies.html -->
    <dependency>
      <groupId>nl.basjes.parse.useragent</groupId>
      <artifactId>yauaa</artifactId>
      <version>${project.version}</version>
      <exclusions>
        <exclusion>
          <groupId>org.antlr</groupId>
          <artifactId>antlr4-runtime</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.yaml</groupId>
          <artifactId>snakeyaml</artifactId>
        </exclusion>

        <!-- Excluded because of dependency convergence -->
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-graphql</artifactId>
      <version>${spring-boot.version}</version>
      <exclusions>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.reactivestreams</groupId>
          <artifactId>reactive-streams</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.yaml</groupId>
          <artifactId>snakeyaml</artifactId>
        </exclusion>
        <exclusion>
          <groupId>io.projectreactor</groupId>
          <artifactId>reactor-core</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-core</artifactId>
      <version>3.8.6</version>
    </dependency>

    <dependency>
      <groupId>org.reactivestreams</groupId>
      <artifactId>reactive-streams</artifactId>
      <version>1.0.4</version>
    </dependency>

    <!-- The webapp needs more classes than have been shaded in. -->
    <dependency>
      <groupId>org.antlr</groupId>
      <artifactId>antlr4-runtime</artifactId>
      <version>[${antlr.version}]</version>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-text</artifactId>
      <version>1.15.0</version>
      <exclusions>
        <exclusion>
          <groupId>org.apache.commons</groupId>
          <artifactId>commons-lang3</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.20.0</version>
    </dependency>

    <!-- ================================================================================================ -->

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
    </dependency>

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
    </dependency>

    <dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>6.0.1</version>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <artifactId>hamcrest</artifactId>
          <groupId>org.hamcrest</groupId>
        </exclusion>
        <exclusion>
          <artifactId>commons-codec</artifactId>
          <groupId>commons-codec</groupId>
        </exclusion>
        <exclusion>
          <artifactId>commons-lang3</artifactId>
          <groupId>org.apache.commons</groupId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

  <build>
    <outputDirectory>target/${project.artifactId}/WEB-INF/classes</outputDirectory>

    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.graalvm.buildtools</groupId>
          <artifactId>native-maven-plugin</artifactId>
          <version>${native-build-tools-plugin.version}</version>
          <extensions>true</extensions>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-toolchains-plugin</artifactId>
        <executions>
          <execution>
            <goals>
              <goal>select-jdk-toolchain</goal>
            </goals>
            <configuration>
              <version>[25,26)</version>
            </configuration>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
      </plugin>


      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <!-- This is because of a problem of surefire in parallel mode in combination with a different toolchain. -->
          <forkCount>1</forkCount>
          <failIfNoTests>true</failIfNoTests>
        </configuration>
      </plugin>

      <plugin>
        <groupId>com.github.spotbugs</groupId>
        <artifactId>spotbugs-maven-plugin</artifactId>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
      </plugin>

      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <configuration>
          <skip>true</skip>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>${spring-boot.version}</version>
        <configuration>
          <mainClass>${main.class}</mainClass>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>repackage</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
          <webResources>
            <!-- in order to interpolate version and main class from pom into {appengine-,}web.xml -->
            <resource>
              <directory>${project.basedir}/src/main/webapp/WEB-INF</directory>
              <filtering>true</filtering>
              <targetPath>WEB-INF</targetPath>
            </resource>
          </webResources>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <executions>
          <execution>
            <id>enforce-quality</id>
            <phase>validate</phase>
            <goals>
              <goal>enforce</goal>
            </goals>
            <configuration>
              <rules>

                <banDuplicateClasses>
                  <scopes>
                    <scope>compile</scope>
                    <scope>runtime</scope>
                    <scope>provided</scope>
                  </scopes>
                  <findAllDuplicates>true</findAllDuplicates>
                  <ignoreWhenIdentical>true</ignoreWhenIdentical>
                </banDuplicateClasses>

              </rules>
              <fail>true</fail>
            </configuration>
          </execution>

        </executions>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>extra-enforcer-rules</artifactId>
            <version>1.12.0</version>
          </dependency>
        </dependencies>
      </plugin>


      <!-- Documentation: https://dmp.fabric8.io/ -->
      <plugin>
        <groupId>io.fabric8</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <version>${docker-maven-plugin.version}</version>

        <configuration>
          <skip>${docker-based-tests.skip}</skip>
          <follow>false</follow>
          <sourceDirectory>src/test/resources</sourceDirectory>
          <images>
            <image>
              <name>nielsbasjes/yauaa:${project.version}</name>
              <build>
                <maintainer>Niels Basjes</maintainer>
                <from>openjdk:21-slim</from>
                <tags>
                  <tag>latest</tag>
                  <tag>${project.version}</tag>
                </tags>

                <labels>
                  <name>yauaa</name>
                  <org.opencontainers.image.created>${maven.build.timestamp}</org.opencontainers.image.created>
                  <org.opencontainers.image.authors>Niels Basjes</org.opencontainers.image.authors>
                  <org.opencontainers.image.url>https://yauaa.basjes.nl</org.opencontainers.image.url>
                  <org.opencontainers.image.documentation>https://yauaa.basjes.nl</org.opencontainers.image.documentation>
                  <org.opencontainers.image.source>https://github.com/nielsbasjes/yauaa</org.opencontainers.image.source>
                  <org.opencontainers.image.version>${project.version}</org.opencontainers.image.version>
                  <!--suppress UnresolvedMavenProperty -->
                  <org.opencontainers.image.revision>${git.commit.id}</org.opencontainers.image.revision>
                  <org.opencontainers.image.vendor>Niels Basjes</org.opencontainers.image.vendor>
                  <org.opencontainers.image.licenses>Apache-2.0</org.opencontainers.image.licenses>
                  <org.opencontainers.image.title>Yauaa: Yet Another UserAgent Analyzer</org.opencontainers.image.title>
                  <org.opencontainers.image.description>This is a java library that tries to parse and analyze the useragent string (and when available the User-Agent Client Hints) and extract as many relevant attributes as possible.</org.opencontainers.image.description>
                </labels>
                <assembly>
                  <name>${project.build.finalName}.war</name>
                  <targetDir>/</targetDir>
                  <mode>dir</mode>
                  <descriptorRef>artifact</descriptorRef>
                </assembly>
                <ports>
                  <port>8080</port>
                </ports>
                <entryPoint>
                  <exec>
                    <arg>java</arg>
                    <arg>-Djava.security.egd=file:/dev/./urandom</arg>
                    <arg>-jar</arg>
                    <arg>/${project.build.finalName}.war</arg>
                  </exec>
                </entryPoint>
              </build>

              <run>
                <skip>true</skip>
              </run>
            </image>

            <image>
              <name>nielsbasjes/yauaa:${project.version}-WITH-EXTRA-CONFIG</name>
              <build>
                <tags>
                  <tag>${project.version}-WITH-EXTRA-CONFIG</tag>
                </tags>
                <dockerFile>ITDockerfile</dockerFile>
              </build>

              <run>
                <containerNamePattern>yauaa-ittest-%i</containerNamePattern>
                <ports>
                  <port>yauaa.port:8080</port>
                </ports>
                <wait>
                  <http>
                    <url>http://localhost:${yauaa.port}/readiness</url>
                  </http>
                  <time>20000</time>
                </wait>
                <log>
                  <prefix>[ LOCAL TEST OF YAUAA WITH CONFIG ]::</prefix>
                  <color>yellow</color>
                </log>
              </run>
            </image>

          </images>
        </configuration>

        <executions>
          <execution>
            <id>build-docker</id>
            <configuration>
              <skip>${docker-based-tests.skip}</skip>
              <removeMode>build</removeMode>
            </configuration>
            <phase>${docker-based-package.phase}</phase>
            <goals>
              <goal>stop</goal>
              <goal>remove</goal>
              <goal>build</goal>
            </goals>
          </execution>

          <execution>
            <id>start-docker-before-it</id>
            <phase>pre-integration-test</phase>
            <configuration>
              <skip>${docker-based-tests.skip}</skip>
            </configuration>
            <goals>
              <goal>stop</goal>
              <goal>start</goal>
            </goals>
          </execution>

          <execution>
            <id>stop-docker-after-it</id>
            <configuration>
              <skip>${docker-based-tests.skip}</skip>
            </configuration>
            <phase>post-integration-test</phase>
            <goals>
              <goal>stop</goal>
            </goals>
          </execution>

        </executions>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-failsafe-plugin</artifactId>
        <executions>
          <execution>
            <id>run-tests</id>
            <configuration>
              <skip>${docker-based-tests.skip}</skip>
            </configuration>
            <phase>integration-test</phase>
            <goals>
              <goal>integration-test</goal>
              <goal>verify</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

    </plugins>

  </build>


  <profiles>
    <profile>
      <id>native</id>
      <build>
        <plugins>

          <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
              <execution>
                <id>Create native output directory</id>
                <phase>package</phase>
                <configuration>
                  <target>
                    <mkdir dir="target/native-image" />
                  </target>
                </configuration>
                <goals>
                  <goal>run</goal>
                </goals>
              </execution>
            </executions>
          </plugin>


          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
              <image>
                <builder>paketobuildpacks/builder:tiny</builder>
                <env>
                  <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
                </env>
              </image>
            </configuration>
            <executions>
              <execution>
                <id>process-aot</id>
                <phase>package</phase>
                <goals>
                  <goal>process-aot</goal>
                </goals>
              </execution>
            </executions>
          </plugin>

          <plugin>
            <groupId>org.graalvm.buildtools</groupId>
            <artifactId>native-maven-plugin</artifactId>
            <configuration>
              <classesDirectory>${project.build.outputDirectory}</classesDirectory>
              <metadataRepository>
                <enabled>true</enabled>
              </metadataRepository>
              <buildArgs>
                <buildArg>-march=x86-64-v1</buildArg>
                <buildArg>-H:Name=${project.build.directory}/native-image/yauaa-webapp-native-${project.version}</buildArg>
              </buildArgs>
            </configuration>
            <executions>
              <execution>
                <id>add-reachability-metadata</id>
                <goals>
                  <goal>add-reachability-metadata</goal>
                </goals>
              </execution>
              <execution>
                <id>compile to native</id>
                <phase>package</phase>
                <goals>
                  <goal>compile</goal>
                </goals>
              </execution>

            </executions>
          </plugin>

          <!-- Documentation: https://dmp.fabric8.io/ -->
          <plugin>
            <groupId>io.fabric8</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>${docker-maven-plugin.version}</version>

            <configuration>
              <!--              <skip>${docker-based-tests.skip}</skip>-->
              <follow>false</follow>
              <sourceDirectory>src/test/resources</sourceDirectory>
              <images>
                <image>
                  <name>nielsbasjes/yauaa:${project.version}-native</name>
                  <build>
                    <maintainer>Niels Basjes</maintainer>
                    <!-- <from>scratch</from> doesn't work because of dependence on shared libraries. -->
                    <from>debian:12</from>
                    <tags>
                      <tag>latest-native</tag>
                      <tag>${project.version}-native</tag>
                    </tags>

                    <labels>
                      <name>yauaa</name>
                      <org.opencontainers.image.created>${maven.build.timestamp}</org.opencontainers.image.created>
                      <org.opencontainers.image.authors>Niels Basjes</org.opencontainers.image.authors>
                      <org.opencontainers.image.url>https://yauaa.basjes.nl</org.opencontainers.image.url>
                      <org.opencontainers.image.documentation>https://yauaa.basjes.nl</org.opencontainers.image.documentation>
                      <org.opencontainers.image.source>https://github.com/nielsbasjes/yauaa</org.opencontainers.image.source>
                      <org.opencontainers.image.version>${project.version}</org.opencontainers.image.version>
                      <!--suppress UnresolvedMavenProperty -->
                      <org.opencontainers.image.revision>${git.commit.id}</org.opencontainers.image.revision>
                      <org.opencontainers.image.vendor>Niels Basjes</org.opencontainers.image.vendor>
                      <org.opencontainers.image.licenses>Apache-2.0</org.opencontainers.image.licenses>
                      <org.opencontainers.image.title>Yauaa: Yet Another UserAgent Analyzer</org.opencontainers.image.title>
                      <org.opencontainers.image.description>This is a java library that tries to parse and analyze the useragent string (and when available the User-Agent Client Hints) and extract as many relevant attributes as possible.</org.opencontainers.image.description>
                    </labels>

                    <assembly>
                      <targetDir>/</targetDir>
                      <inline>
                        <fileSets>
                          <fileSet>
                            <directory>${project.build.directory}/native-image</directory>
                            <outputDirectory>/</outputDirectory>
                          </fileSet>
                        </fileSets>
                      </inline>
                    </assembly>
                    <ports>
                      <port>8080</port>
                    </ports>
                    <entryPoint>
                      <exec>
                        <arg>/yauaa-webapp-native-${project.version}</arg>
                      </exec>
                    </entryPoint>
                  </build>

                  <run>
                    <skip>true</skip>
                  </run>
                </image>

                <image>
                  <name>nielsbasjes/yauaa:${project.version}-native-WITH-EXTRA-CONFIG</name>
                  <build>
                    <tags>
                      <tag>${project.version}-native-WITH-EXTRA-CONFIG</tag>
                    </tags>
                    <dockerFile>ITDockerfile-native</dockerFile>
                  </build>

                  <run>
                    <containerNamePattern>yauaa-ittest-native-%i</containerNamePattern>
                    <ports>
                      <port>yauaa.port:8080</port>
                    </ports>
                    <wait>
                      <http>
                        <url>http://localhost:${yauaa.port}/readiness</url>
                      </http>
                      <time>20000</time>
                    </wait>
                    <log>
                      <prefix>[ LOCAL TEST OF NATIVE YAUAA WITH CONFIG ]::</prefix>
                      <color>yellow</color>
                    </log>
                  </run>
                </image>

              </images>
            </configuration>

            <executions>
              <execution>
                <id>build-docker</id>
                <configuration>
                  <skip>${docker-based-tests.skip}</skip>
                  <removeMode>build</removeMode>
                </configuration>
                <phase>${docker-based-package.phase}</phase>
                <goals>
                  <goal>stop</goal>
                  <goal>remove</goal>
                  <goal>build</goal>
                </goals>
              </execution>

              <execution>
                <id>start-docker-before-it</id>
                <phase>pre-integration-test</phase>
                <configuration>
                  <skip>${docker-based-tests.skip}</skip>
                </configuration>
                <goals>
                  <goal>stop</goal>
                  <goal>start</goal>
                </goals>
              </execution>

              <execution>
                <id>stop-docker-after-it</id>
                <configuration>
                  <skip>${docker-based-tests.skip}</skip>
                </configuration>
                <phase>post-integration-test</phase>
                <goals>
                  <goal>stop</goal>
                </goals>
              </execution>

            </executions>
          </plugin>

        </plugins>
      </build>
    </profile>

  </profiles>

</project>
