<?xml version="1.0" encoding="UTF-8"?>
<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>cloud.opencode.base</groupId>
    <artifactId>opencode-base-parent</artifactId>
    <version>1.0.4</version>
    <packaging>pom</packaging>

    <name>OpenCode Base Parent</name>
    <description>OpenCode Base - A modern Java utility library for JDK 25+</description>
    <url>https://opencode.cloud</url>

    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <developers>
        <developer>
            <name>Leon Soo</name>
            <url>https://leonsoo.com</url>
            <organization>OpenCode</organization>
            <organizationUrl>https://opencode.cloud</organizationUrl>
        </developer>
    </developers>

    <scm>
        <connection>scm:git:git://github.com/opencodecloud/opencode-base.git</connection>
        <developerConnection>scm:git:ssh://github.com/opencodecloud/opencode-base.git</developerConnection>
        <url>https://github.com/opencodecloud/opencode-base</url>
    </scm>

    <issueManagement>
        <system>GitHub Issues</system>
        <url>https://github.com/opencodecloud/opencode-base/issues</url>
    </issueManagement>

    <properties>
        <!-- 本 BOM 自身版本字面量（勿用 ${project.version}，在继承方会被重新求值） -->
        <opencode.base.version>1.0.4</opencode.base.version>

        <!-- 基础设施 / Infrastructure -->
        <java.version>25</java.version>
        <maven.compiler.release>${java.version}</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <project.build.outputTimestamp>2026-04-15T06:27:36Z</project.build.outputTimestamp>

        <!-- 测试依赖版本 / Test dependency versions -->
        <junit.version>5.11.2</junit.version>
        <assertj.version>3.26.3</assertj.version>
        <mockito.version>5.14.2</mockito.version>
        <jmh.version>1.37</jmh.version>

        <!-- Surefire argLine 默认值（JaCoCo prepare-agent 激活时会覆盖） -->
        <argLine></argLine>

        <!-- 可选外部依赖版本 / Optional external dependency versions -->
        <!-- BouncyCastle: optional dep, declared in opencode-base-crypto only and marked
             {@code <optional>true</optional>} so it does NOT transitively pollute downstream
             consumers. Bumped 1.79 → 1.80 in the V1.0.4 sec round-3 sweep to track the
             current LTS line; consumers who explicitly add BC themselves can override the
             version via their own dependencyManagement.
             BouncyCastle：可选依赖，仅 opencode-base-crypto 声明且标 {@code <optional>true</optional>}，
             不向下游消费者传递。V1.0.4 sec round-3 把 1.79 升到 1.80 以跟踪当前 LTS；显式引入 BC
             的消费者可在自己的 dependencyManagement 覆盖版本。 -->
        <bouncycastle.version>1.80</bouncycastle.version>

        <!-- 插件版本 / Plugin versions -->
        <maven-compiler-plugin.version>3.14.1</maven-compiler-plugin.version>
        <maven-surefire-plugin.version>3.5.0</maven-surefire-plugin.version>
        <maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
        <maven-source-plugin.version>3.3.1</maven-source-plugin.version>
        <maven-javadoc-plugin.version>3.10.1</maven-javadoc-plugin.version>
        <maven-gpg-plugin.version>3.2.7</maven-gpg-plugin.version>
        <maven-enforcer-plugin.version>3.5.0</maven-enforcer-plugin.version>
        <central-publishing-plugin.version>0.6.0</central-publishing-plugin.version>
        <cyclonedx-plugin.version>2.9.1</cyclonedx-plugin.version>

        <!-- 质量门控 / Quality gates -->
        <jacoco.version>0.8.14</jacoco.version>
        <jacoco.minimum.coverage>0.80</jacoco.minimum.coverage>
    </properties>

    <modules>
        <module>opencode-base-core</module>
        <module>opencode-base-cache</module>
        <module>opencode-base-classloader</module>
        <module>opencode-base-collections</module>
        <module>opencode-base-config</module>
        <module>opencode-base-crypto</module>
        <module>opencode-base-date</module>
        <module>opencode-base-deepclone</module>
        <module>opencode-base-email</module>
        <module>opencode-base-functional</module>
        <module>opencode-base-hash</module>
        <module>opencode-base-json</module>
        <module>opencode-base-i18n</module>
        <module>opencode-base-id</module>
        <module>opencode-base-io</module>
        <module>opencode-base-reflect</module>
        <module>opencode-base-string</module>
        <module>opencode-base-log</module>
        <module>opencode-base-parallel</module>
        <module>opencode-base-pool</module>
        <module>opencode-base-serialization</module>
        <module>opencode-base-xml</module>
        <module>opencode-base-yml</module>
        <module>opencode-base-captcha</module>
        <module>opencode-base-event</module>
        <module>opencode-base-feature</module>
        <module>opencode-base-geo</module>
        <module>opencode-base-graph</module>
        <module>opencode-base-image</module>
        <module>opencode-base-image-codec</module>
        <module>opencode-base-lunar</module>
        <module>opencode-base-money</module>
        <module>opencode-base-test</module>
        <module>opencode-base-timeseries</module>
        <module>opencode-base-tree</module>
        <module>opencode-base-web</module>
        <module>opencode-base-oauth2</module>
        <module>opencode-base-expression</module>
        <module>opencode-base-lock</module>
        <module>opencode-base-rules</module>
        <module>opencode-base-pdf</module>
        <module>opencode-base-cron</module>
        <module>opencode-base-observability</module>
        <module>opencode-base-neural</module>
        <module>opencode-base-csv</module>
        <module>opencode-base-math</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <!-- 内部模块 / Internal modules -->
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-core</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-cache</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-captcha</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-classloader</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-collections</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-config</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-crypto</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-date</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-deepclone</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-event</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-expression</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-feature</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-functional</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-geo</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-graph</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-hash</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-i18n</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-id</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-image</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-image-codec</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-io</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-json</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-lock</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-log</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-lunar</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-money</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-neural</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-oauth2</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-observability</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-parallel</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-pdf</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-pool</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-reflect</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-rules</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-serialization</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-string</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-test</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-timeseries</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-tree</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-web</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-xml</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>
            <dependency>
                <groupId>cloud.opencode.base</groupId>
                <artifactId>opencode-base-yml</artifactId>
                <version>${opencode.base.version}</version>
            </dependency>

            <!-- 测试依赖 / Test dependencies -->
            <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.assertj</groupId>
                <artifactId>assertj-core</artifactId>
                <version>${assertj.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>${mockito.version}</version>
                <scope>test</scope>
            </dependency>
            <!-- JMH 基准测试（仅 test scope，业界标准） / JMH benchmark (test only, industry standard) -->
            <dependency>
                <groupId>org.openjdk.jmh</groupId>
                <artifactId>jmh-core</artifactId>
                <version>${jmh.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.openjdk.jmh</groupId>
                <artifactId>jmh-generator-annprocess</artifactId>
                <version>${jmh.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <pluginManagement>
            <plugins>
                <!-- 编译器 / Compiler -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>${maven-compiler-plugin.version}</version>
                    <configuration>
                        <release>${java.version}</release>
                        <parameters>true</parameters>
                    </configuration>
                </plugin>
                <!-- 测试执行 / Test runner -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>${maven-surefire-plugin.version}</version>
                    <configuration>
                        <argLine>@{argLine} --enable-native-access=ALL-UNNAMED --sun-misc-unsafe-memory-access=allow -XX:+EnableDynamicAgentLoading</argLine>
                    </configuration>
                </plugin>
                <!-- JAR 打包 / JAR packaging -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <version>${maven-jar-plugin.version}</version>
                </plugin>
                <!-- 源码包 / Source jar -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-source-plugin</artifactId>
                    <version>${maven-source-plugin.version}</version>
                    <executions>
                        <execution>
                            <id>attach-sources</id>
                            <goals><goal>jar-no-fork</goal></goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- Javadoc 包 / Javadoc jar -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <version>${maven-javadoc-plugin.version}</version>
                    <configuration>
                        <release>${java.version}</release>
                        <doclint>html,syntax,reference</doclint>
                        <tags>
                            <tag>
                                <name>apiNote</name>
                                <placement>a</placement>
                                <head>API Note:</head>
                            </tag>
                            <tag>
                                <name>implSpec</name>
                                <placement>a</placement>
                                <head>Implementation Requirements:</head>
                            </tag>
                            <tag>
                                <name>implNote</name>
                                <placement>a</placement>
                                <head>Implementation Note:</head>
                            </tag>
                        </tags>
                    </configuration>
                    <executions>
                        <execution>
                            <id>attach-javadocs</id>
                            <goals><goal>jar</goal></goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- GPG 签名 / GPG signing -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-gpg-plugin</artifactId>
                    <version>${maven-gpg-plugin.version}</version>
                    <configuration>
                        <gpgArguments>
                            <arg>--pinentry-mode</arg>
                            <arg>loopback</arg>
                        </gpgArguments>
                    </configuration>
                    <executions>
                        <execution>
                            <id>sign-artifacts</id>
                            <phase>verify</phase>
                            <goals><goal>sign</goal></goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- Maven Central 发布 / Maven Central publishing -->
                <plugin>
                    <groupId>org.sonatype.central</groupId>
                    <artifactId>central-publishing-maven-plugin</artifactId>
                    <version>${central-publishing-plugin.version}</version>
                    <extensions>true</extensions>
                    <configuration>
                        <publishingServerId>central</publishingServerId>
                        <autoPublish>true</autoPublish>
                        <waitUntil>published</waitUntil>
                    </configuration>
                </plugin>
                <!-- SBOM 生成 / SBOM generation -->
                <plugin>
                    <groupId>org.cyclonedx</groupId>
                    <artifactId>cyclonedx-maven-plugin</artifactId>
                    <version>${cyclonedx-plugin.version}</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals><goal>makeAggregateBom</goal></goals>
                        </execution>
                    </executions>
                </plugin>
                <!-- 构建约束 / Build enforcement -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-enforcer-plugin</artifactId>
                    <version>${maven-enforcer-plugin.version}</version>
                    <executions>
                        <execution>
                            <id>enforce</id>
                            <goals><goal>enforce</goal></goals>
                            <configuration>
                                <rules>
                                    <!-- 要求 JDK 25+ / Require JDK 25+ -->
                                    <requireJavaVersion>
                                        <version>[25,)</version>
                                        <message>${project.name} requires JDK 25 or later.</message>
                                    </requireJavaVersion>
                                    <!-- 要求 Maven 3.9+ / Require Maven 3.9+ -->
                                    <requireMavenVersion>
                                        <version>[3.9.0,)</version>
                                        <message>${project.name} requires Maven 3.9.0 or later.</message>
                                    </requireMavenVersion>
                                    <!-- 禁止重复依赖 / Ban duplicate dependencies -->
                                    <banDuplicatePomDependencyVersions/>
                                </rules>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <!-- 代码覆盖率 / Code coverage -->
                <plugin>
                    <groupId>org.jacoco</groupId>
                    <artifactId>jacoco-maven-plugin</artifactId>
                    <version>${jacoco.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>prepare-agent</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>report</id>
                            <phase>test</phase>
                            <goals>
                                <goal>report</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>check</id>
                            <goals>
                                <goal>check</goal>
                            </goals>
                            <configuration>
                                <rules>
                                    <rule>
                                        <element>BUNDLE</element>
                                        <limits>
                                            <limit>
                                                <counter>INSTRUCTION</counter>
                                                <value>COVEREDRATIO</value>
                                                <minimum>${jacoco.minimum.coverage}</minimum>
                                            </limit>
                                        </limits>
                                    </rule>
                                </rules>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>

        <!-- 全局激活非默认生命周期插件 / Globally activate non-default lifecycle plugins -->
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
            </plugin>
            <!-- enforcer 暂不全局激活：3.5.0 内置 ASM 不兼容 JDK 25 class version 69 -->
            <!-- Tracking: re-enable once maven-enforcer-plugin ships an ASM-9.7+ build -->
            <!-- (Apache Maven Enforcer 4.x line, currently in milestone — check semi-annually). -->
            <!-- 跟踪：等 maven-enforcer-plugin 发布内置 ASM-9.7+ 的版本（目前 4.x 在里程碑阶段， -->
            <!-- 半年回检一次）后取消注释。 -->
            <!--
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-enforcer-plugin</artifactId>
            </plugin>
            -->
        </plugins>
    </build>

    <!-- 发布 Profile / Release profile -->
    <profiles>
        <profile>
            <id>release</id>
            <build>
                <plugins>
                    <plugin><artifactId>maven-source-plugin</artifactId></plugin>
                    <plugin>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <!-- V1.0.4 release: relax doclint to ship javadoc artifacts despite
                             20 outstanding cross-module @see / HTML / @param issues across
                             9 modules. Tracked for V1.0.5 cleanup. Maven Central accepts
                             javadoc-jar regardless of warnings.
                             V1.0.4 发布：放宽 doclint 让 javadoc-jar 能产出（9 个模块共
                             20 项跨模块 @see / HTML 实体 / @param 问题，留 V1.0.5 清理）。
                             Maven Central 接收 javadoc-jar 不卡 warning。 -->
                        <configuration>
                            <doclint>none</doclint>
                            <failOnError>false</failOnError>
                            <failOnWarnings>false</failOnWarnings>
                        </configuration>
                    </plugin>
                    <plugin><artifactId>maven-gpg-plugin</artifactId></plugin>
                    <plugin>
                        <groupId>org.sonatype.central</groupId>
                        <artifactId>central-publishing-maven-plugin</artifactId>
                    </plugin>
                    <plugin>
                        <groupId>org.cyclonedx</groupId>
                        <artifactId>cyclonedx-maven-plugin</artifactId>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>
