6
0
Files
maven-jar-plugin/maven-jar-plugin-bootstrap-resources.patch

1319 lines
60 KiB
Diff

--- maven-jar-plugin-3.4.2/src/main/filtered-resources/META-INF/maven/org.apache.maven.plugins/maven-jar-plugin/plugin-help.xml 1970-01-01 01:00:00.000000000 +0100
+++ maven-jar-plugin-3.4.2/src/main/filtered-resources/META-INF/maven/org.apache.maven.plugins/maven-jar-plugin/plugin-help.xml 2025-06-06 17:21:28.384603798 +0200
@@ -0,0 +1,343 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin>
+ <name>${project.name}</name>
+ <description>${project.description}</description>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>${project.artifactId}</artifactId>
+ <version>${project.version}</version>
+ <goalPrefix>jar</goalPrefix>
+ <mojos>
+ <mojo>
+ <goal>help</goal>
+ <description>Display help information on maven-jar-plugin.
+Call mvn jar:help -Ddetail=true -Dgoal=&lt;goal-name&gt; to display parameter details.</description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>false</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.apache.maven.plugins.maven_jar_plugin.HelpMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <threadSafe>true</threadSafe>
+ <parameters>
+ <parameter>
+ <name>detail</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If true, display all settable properties for each goal.</description>
+ </parameter>
+ <parameter>
+ <name>goal</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The name of the goal for which to show help. If unspecified, all goals will be displayed.</description>
+ </parameter>
+ <parameter>
+ <name>indentSize</name>
+ <type>int</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The number of spaces per indentation level, should be positive.</description>
+ </parameter>
+ <parameter>
+ <name>lineLength</name>
+ <type>int</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The maximum length of a display line, should be positive.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <detail implementation="boolean" default-value="false">${detail}</detail>
+ <goal implementation="java.lang.String">${goal}</goal>
+ <indentSize implementation="int" default-value="2">${indentSize}</indentSize>
+ <lineLength implementation="int" default-value="80">${lineLength}</lineLength>
+ </configuration>
+ </mojo>
+ <mojo>
+ <goal>jar</goal>
+ <description>Build a JAR from the current project.</description>
+ <requiresDependencyResolution>runtime</requiresDependencyResolution>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>true</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <phase>package</phase>
+ <implementation>org.apache.maven.plugins.jar.JarMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <threadSafe>true</threadSafe>
+ <parameters>
+ <parameter>
+ <name>addDefaultExcludes</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If set to false, the files and directories that by default are excluded from the resulting archive, like .gitignore, .cvsignore etc. will be included. This means all files like the following will be included.
+* Misc: **/*~, **/#*#, **/.#*, **/%*%, **/._*
+* CVS: **/CVS, **/CVS/**, **/.cvsignore
+* RCS: **/RCS, **/RCS/**
+* SCCS: **/SCCS, **/SCCS/**
+* VSSercer: **/vssver.scc
+* MKS: **/project.pj
+* SVN: **/.svn, **/.svn/**
+* GNU: **/.arch-ids, **/.arch-ids/**
+* Bazaar: **/.bzr, **/.bzr/**
+* SurroundSCM: **/.MySCMServerInfo
+* Mac: **/.DS_Store
+* Serena Dimension: **/.metadata, **/.metadata/**
+* Mercurial: **/.hg, **/.hg/**
+* Git: **/.git, **/.git/**
+* Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet, **/ChangeSet/**
+* Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo, **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail
+See also: DEFAULTEXCLUDES &lt;https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/AbstractScanner.html#DEFAULTEXCLUDES&gt;</description>
+ </parameter>
+ <parameter>
+ <name>archive</name>
+ <type>org.apache.maven.archiver.MavenArchiveConfiguration</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The archive configuration to use. See Maven Archiver Reference &lt;http://maven.apache.org/shared/maven-archiver/index.html&gt;.</description>
+ </parameter>
+ <parameter>
+ <name>classesDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the classes and resource files that should be packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>classifier</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Classifier to add to the artifact generated. If given, the artifact will be attached as a supplemental artifact. If not given this will create the main artifact which is the default behavior. If you try to do that a second time without using a classifier the build will fail.</description>
+ </parameter>
+ <parameter>
+ <name>detectMultiReleaseJar</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If the JAR contains the META-INF/versions directory it will be detected as a multi-release JAR file (&quot;MRJAR&quot;), adding the Multi-Release: true attribute to the main section of the JAR MANIFEST.MF.</description>
+ </parameter>
+ <parameter>
+ <name>excludes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>forceCreation</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Require the jar plugin to build a new JAR even if none of the contents appear to have changed. By default, this plugin looks to see if the output jar exists and inputs have not changed. If these conditions are true, the plugin skips creation of the jar. This does not work when other plugins, like the maven-shade-plugin, are configured to post-process the jar. This plugin can not detect the post-processing, and so leaves the post-processed jar in place. This can lead to failures when those plugins do not expect to find their own output as an input. Set this parameter to true to avoid these problems by forcing this plugin to recreate the jar every time.
+Starting with 3.0.0 the property has been renamed from jar.forceCreation to maven.jar.forceCreation.</description>
+ </parameter>
+ <parameter>
+ <name>includes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to include. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the generated JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputTimestamp</name>
+ <type>java.lang.String</type>
+ <since>3.2.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended offset date-time (e.g. in UTC such as &apos;2011-12-03T10:15:30Z&apos; or with an offset &apos;2019-10-05T20:37:42+06:00&apos;), or as an int representing seconds since the epoch (like SOURCE_DATE_EPOCH &lt;https://reproducible-builds.org/docs/source-date-epoch/&gt;).</description>
+ </parameter>
+ <parameter>
+ <name>skipIfEmpty</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Skip creating empty archives.</description>
+ </parameter>
+ <parameter>
+ <name>useDefaultManifestFile</name>
+ <type>boolean</type>
+ <deprecated>For version 3.0.0 this parameter is only defined here to break the build if you use it!</deprecated>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Using this property will fail your build cause it has been removed from the plugin configuration. See the Major Version Upgrade to version 3.0.0 &lt;https://maven.apache.org/plugins/maven-jar-plugin/&gt; for the plugin.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <addDefaultExcludes implementation="boolean" default-value="true"/>
+ <classesDirectory implementation="java.io.File" default-value="${project.build.outputDirectory}"/>
+ <detectMultiReleaseJar implementation="boolean" default-value="true">${maven.jar.detectMultiReleaseJar}</detectMultiReleaseJar>
+ <forceCreation implementation="boolean" default-value="false">${maven.jar.forceCreation}</forceCreation>
+ <outputDirectory implementation="java.io.File" default-value="${project.build.directory}"/>
+ <outputTimestamp implementation="java.lang.String" default-value="${project.build.outputTimestamp}"/>
+ <skipIfEmpty implementation="boolean" default-value="false"/>
+ <useDefaultManifestFile implementation="boolean" default-value="false">${jar.useDefaultManifestFile}</useDefaultManifestFile>
+ </configuration>
+ </mojo>
+ <mojo>
+ <goal>test-jar</goal>
+ <description>Build a JAR of the test classes for the current project.</description>
+ <requiresDependencyResolution>test</requiresDependencyResolution>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>true</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <phase>package</phase>
+ <implementation>org.apache.maven.plugins.jar.TestJarMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <threadSafe>true</threadSafe>
+ <parameters>
+ <parameter>
+ <name>addDefaultExcludes</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If set to false, the files and directories that by default are excluded from the resulting archive, like .gitignore, .cvsignore etc. will be included. This means all files like the following will be included.
+* Misc: **/*~, **/#*#, **/.#*, **/%*%, **/._*
+* CVS: **/CVS, **/CVS/**, **/.cvsignore
+* RCS: **/RCS, **/RCS/**
+* SCCS: **/SCCS, **/SCCS/**
+* VSSercer: **/vssver.scc
+* MKS: **/project.pj
+* SVN: **/.svn, **/.svn/**
+* GNU: **/.arch-ids, **/.arch-ids/**
+* Bazaar: **/.bzr, **/.bzr/**
+* SurroundSCM: **/.MySCMServerInfo
+* Mac: **/.DS_Store
+* Serena Dimension: **/.metadata, **/.metadata/**
+* Mercurial: **/.hg, **/.hg/**
+* Git: **/.git, **/.git/**
+* Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet, **/ChangeSet/**
+* Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo, **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail
+See also: DEFAULTEXCLUDES &lt;https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/AbstractScanner.html#DEFAULTEXCLUDES&gt;</description>
+ </parameter>
+ <parameter>
+ <name>archive</name>
+ <type>org.apache.maven.archiver.MavenArchiveConfiguration</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The archive configuration to use. See Maven Archiver Reference &lt;http://maven.apache.org/shared/maven-archiver/index.html&gt;.</description>
+ </parameter>
+ <parameter>
+ <name>classifier</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Classifier to use for test-jar.</description>
+ </parameter>
+ <parameter>
+ <name>detectMultiReleaseJar</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If the JAR contains the META-INF/versions directory it will be detected as a multi-release JAR file (&quot;MRJAR&quot;), adding the Multi-Release: true attribute to the main section of the JAR MANIFEST.MF.</description>
+ </parameter>
+ <parameter>
+ <name>excludes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>forceCreation</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Require the jar plugin to build a new JAR even if none of the contents appear to have changed. By default, this plugin looks to see if the output jar exists and inputs have not changed. If these conditions are true, the plugin skips creation of the jar. This does not work when other plugins, like the maven-shade-plugin, are configured to post-process the jar. This plugin can not detect the post-processing, and so leaves the post-processed jar in place. This can lead to failures when those plugins do not expect to find their own output as an input. Set this parameter to true to avoid these problems by forcing this plugin to recreate the jar every time.
+Starting with 3.0.0 the property has been renamed from jar.forceCreation to maven.jar.forceCreation.</description>
+ </parameter>
+ <parameter>
+ <name>includes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to include. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the generated JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputTimestamp</name>
+ <type>java.lang.String</type>
+ <since>3.2.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended offset date-time (e.g. in UTC such as &apos;2011-12-03T10:15:30Z&apos; or with an offset &apos;2019-10-05T20:37:42+06:00&apos;), or as an int representing seconds since the epoch (like SOURCE_DATE_EPOCH &lt;https://reproducible-builds.org/docs/source-date-epoch/&gt;).</description>
+ </parameter>
+ <parameter>
+ <name>skip</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Set this to true to bypass test-jar generation. Its use is NOT RECOMMENDED, but quite convenient on occasion.</description>
+ </parameter>
+ <parameter>
+ <name>skipIfEmpty</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Skip creating empty archives.</description>
+ </parameter>
+ <parameter>
+ <name>testClassesDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the test classes and resource files that should be packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>useDefaultManifestFile</name>
+ <type>boolean</type>
+ <deprecated>For version 3.0.0 this parameter is only defined here to break the build if you use it!</deprecated>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Using this property will fail your build cause it has been removed from the plugin configuration. See the Major Version Upgrade to version 3.0.0 &lt;https://maven.apache.org/plugins/maven-jar-plugin/&gt; for the plugin.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <addDefaultExcludes implementation="boolean" default-value="true"/>
+ <classifier implementation="java.lang.String" default-value="tests"/>
+ <detectMultiReleaseJar implementation="boolean" default-value="true">${maven.jar.detectMultiReleaseJar}</detectMultiReleaseJar>
+ <forceCreation implementation="boolean" default-value="false">${maven.jar.forceCreation}</forceCreation>
+ <outputDirectory implementation="java.io.File" default-value="${project.build.directory}"/>
+ <outputTimestamp implementation="java.lang.String" default-value="${project.build.outputTimestamp}"/>
+ <skip implementation="boolean">${maven.test.skip}</skip>
+ <skipIfEmpty implementation="boolean" default-value="false"/>
+ <testClassesDirectory implementation="java.io.File" default-value="${project.build.testOutputDirectory}"/>
+ <useDefaultManifestFile implementation="boolean" default-value="false">${jar.useDefaultManifestFile}</useDefaultManifestFile>
+ </configuration>
+ </mojo>
+ </mojos>
+</plugin>
--- maven-jar-plugin-3.4.2/src/main/filtered-resources/META-INF/maven/plugin.xml 1970-01-01 01:00:00.000000000 +0100
+++ maven-jar-plugin-3.4.2/src/main/filtered-resources/META-INF/maven/plugin.xml 2025-06-06 17:27:59.026728612 +0200
@@ -0,0 +1,517 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<plugin>
+ <name>${project.name}</name>
+ <description>${project.description}</description>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>${project.artifactId}</artifactId>
+ <version>${project.version}</version>
+ <goalPrefix>jar</goalPrefix>
+ <isolatedRealm>false</isolatedRealm>
+ <inheritedByDefault>true</inheritedByDefault>
+ <requiredJavaVersion>1.8</requiredJavaVersion>
+ <requiredMavenVersion>3.6.3</requiredMavenVersion>
+ <mojos>
+ <mojo>
+ <goal>help</goal>
+ <description>Display help information on maven-jar-plugin.
+Call mvn jar:help -Ddetail=true -Dgoal=&lt;goal-name&gt; to display parameter details.</description>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>false</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <implementation>org.apache.maven.plugins.maven_jar_plugin.HelpMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <threadSafe>true</threadSafe>
+ <parameters>
+ <parameter>
+ <name>detail</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If true, display all settable properties for each goal.</description>
+ </parameter>
+ <parameter>
+ <name>goal</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The name of the goal for which to show help. If unspecified, all goals will be displayed.</description>
+ </parameter>
+ <parameter>
+ <name>indentSize</name>
+ <type>int</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The number of spaces per indentation level, should be positive.</description>
+ </parameter>
+ <parameter>
+ <name>lineLength</name>
+ <type>int</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The maximum length of a display line, should be positive.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <detail implementation="boolean" default-value="false">${detail}</detail>
+ <goal implementation="java.lang.String">${goal}</goal>
+ <indentSize implementation="int" default-value="2">${indentSize}</indentSize>
+ <lineLength implementation="int" default-value="80">${lineLength}</lineLength>
+ </configuration>
+ </mojo>
+ <mojo>
+ <goal>jar</goal>
+ <description>Build a JAR from the current project.</description>
+ <requiresDependencyResolution>runtime</requiresDependencyResolution>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>true</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <phase>package</phase>
+ <implementation>org.apache.maven.plugins.jar.JarMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <threadSafe>true</threadSafe>
+ <parameters>
+ <parameter>
+ <name>addDefaultExcludes</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If set to false, the files and directories that by default are excluded from the resulting archive, like .gitignore, .cvsignore etc. will be included. This means all files like the following will be included.
+* Misc: **/*~, **/#*#, **/.#*, **/%*%, **/._*
+* CVS: **/CVS, **/CVS/**, **/.cvsignore
+* RCS: **/RCS, **/RCS/**
+* SCCS: **/SCCS, **/SCCS/**
+* VSSercer: **/vssver.scc
+* MKS: **/project.pj
+* SVN: **/.svn, **/.svn/**
+* GNU: **/.arch-ids, **/.arch-ids/**
+* Bazaar: **/.bzr, **/.bzr/**
+* SurroundSCM: **/.MySCMServerInfo
+* Mac: **/.DS_Store
+* Serena Dimension: **/.metadata, **/.metadata/**
+* Mercurial: **/.hg, **/.hg/**
+* Git: **/.git, **/.git/**
+* Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet, **/ChangeSet/**
+* Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo, **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail
+See also: DEFAULTEXCLUDES &lt;https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/AbstractScanner.html#DEFAULTEXCLUDES&gt;</description>
+ </parameter>
+ <parameter>
+ <name>archive</name>
+ <type>org.apache.maven.archiver.MavenArchiveConfiguration</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The archive configuration to use. See Maven Archiver Reference &lt;http://maven.apache.org/shared/maven-archiver/index.html&gt;.</description>
+ </parameter>
+ <parameter>
+ <name>classesDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the classes and resource files that should be packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>classifier</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Classifier to add to the artifact generated. If given, the artifact will be attached as a supplemental artifact. If not given this will create the main artifact which is the default behavior. If you try to do that a second time without using a classifier the build will fail.</description>
+ </parameter>
+ <parameter>
+ <name>detectMultiReleaseJar</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If the JAR contains the META-INF/versions directory it will be detected as a multi-release JAR file (&quot;MRJAR&quot;), adding the Multi-Release: true attribute to the main section of the JAR MANIFEST.MF.</description>
+ </parameter>
+ <parameter>
+ <name>excludes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>finalName</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>false</editable>
+ <description>Name of the generated JAR.</description>
+ </parameter>
+ <parameter>
+ <name>forceCreation</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Require the jar plugin to build a new JAR even if none of the contents appear to have changed. By default, this plugin looks to see if the output jar exists and inputs have not changed. If these conditions are true, the plugin skips creation of the jar. This does not work when other plugins, like the maven-shade-plugin, are configured to post-process the jar. This plugin can not detect the post-processing, and so leaves the post-processed jar in place. This can lead to failures when those plugins do not expect to find their own output as an input. Set this parameter to true to avoid these problems by forcing this plugin to recreate the jar every time.
+Starting with 3.0.0 the property has been renamed from jar.forceCreation to maven.jar.forceCreation.</description>
+ </parameter>
+ <parameter>
+ <name>includes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to include. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the generated JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputTimestamp</name>
+ <type>java.lang.String</type>
+ <since>3.2.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended offset date-time (e.g. in UTC such as &apos;2011-12-03T10:15:30Z&apos; or with an offset &apos;2019-10-05T20:37:42+06:00&apos;), or as an int representing seconds since the epoch (like SOURCE_DATE_EPOCH &lt;https://reproducible-builds.org/docs/source-date-epoch/&gt;).</description>
+ </parameter>
+ <parameter>
+ <name>project</name>
+ <type>org.apache.maven.project.MavenProject</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The org.apache.maven.project.MavenProject.</description>
+ </parameter>
+ <parameter>
+ <name>session</name>
+ <type>org.apache.maven.execution.MavenSession</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The org.apache.maven.execution.MavenSession.</description>
+ </parameter>
+ <parameter>
+ <name>skipIfEmpty</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Skip creating empty archives.</description>
+ </parameter>
+ <parameter>
+ <name>useDefaultManifestFile</name>
+ <type>boolean</type>
+ <deprecated>For version 3.0.0 this parameter is only defined here to break the build if you use it!</deprecated>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Using this property will fail your build cause it has been removed from the plugin configuration. See the Major Version Upgrade to version 3.0.0 &lt;https://maven.apache.org/plugins/maven-jar-plugin/&gt; for the plugin.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <addDefaultExcludes implementation="boolean" default-value="true"/>
+ <classesDirectory implementation="java.io.File" default-value="${project.build.outputDirectory}"/>
+ <detectMultiReleaseJar implementation="boolean" default-value="true">${maven.jar.detectMultiReleaseJar}</detectMultiReleaseJar>
+ <finalName implementation="java.lang.String" default-value="${project.build.finalName}"/>
+ <forceCreation implementation="boolean" default-value="false">${maven.jar.forceCreation}</forceCreation>
+ <outputDirectory implementation="java.io.File" default-value="${project.build.directory}"/>
+ <outputTimestamp implementation="java.lang.String" default-value="${project.build.outputTimestamp}"/>
+ <project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
+ <session implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
+ <skipIfEmpty implementation="boolean" default-value="false"/>
+ <useDefaultManifestFile implementation="boolean" default-value="false">${jar.useDefaultManifestFile}</useDefaultManifestFile>
+ </configuration>
+ <requirements>
+ <requirement>
+ <role>java.util.Map</role>
+ <field-name>archivers</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.project.MavenProjectHelper</role>
+ <field-name>projectHelper</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.toolchain.ToolchainManager</role>
+ <field-name>toolchainManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.plugins.jar.ToolchainsJdkSpecification</role>
+ <field-name>toolchainsJdkSpecification</field-name>
+ </requirement>
+ </requirements>
+ </mojo>
+ <mojo>
+ <goal>test-jar</goal>
+ <description>Build a JAR of the test classes for the current project.</description>
+ <requiresDependencyResolution>test</requiresDependencyResolution>
+ <requiresDirectInvocation>false</requiresDirectInvocation>
+ <requiresProject>true</requiresProject>
+ <requiresReports>false</requiresReports>
+ <aggregator>false</aggregator>
+ <requiresOnline>false</requiresOnline>
+ <inheritedByDefault>true</inheritedByDefault>
+ <phase>package</phase>
+ <implementation>org.apache.maven.plugins.jar.TestJarMojo</implementation>
+ <language>java</language>
+ <instantiationStrategy>per-lookup</instantiationStrategy>
+ <executionStrategy>once-per-session</executionStrategy>
+ <threadSafe>true</threadSafe>
+ <parameters>
+ <parameter>
+ <name>addDefaultExcludes</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If set to false, the files and directories that by default are excluded from the resulting archive, like .gitignore, .cvsignore etc. will be included. This means all files like the following will be included.
+* Misc: **/*~, **/#*#, **/.#*, **/%*%, **/._*
+* CVS: **/CVS, **/CVS/**, **/.cvsignore
+* RCS: **/RCS, **/RCS/**
+* SCCS: **/SCCS, **/SCCS/**
+* VSSercer: **/vssver.scc
+* MKS: **/project.pj
+* SVN: **/.svn, **/.svn/**
+* GNU: **/.arch-ids, **/.arch-ids/**
+* Bazaar: **/.bzr, **/.bzr/**
+* SurroundSCM: **/.MySCMServerInfo
+* Mac: **/.DS_Store
+* Serena Dimension: **/.metadata, **/.metadata/**
+* Mercurial: **/.hg, **/.hg/**
+* Git: **/.git, **/.git/**
+* Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet, **/ChangeSet/**
+* Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo, **/.darcsrepo/****/-darcs-backup*, **/.darcs-temp-mail
+See also: DEFAULTEXCLUDES &lt;https://codehaus-plexus.github.io/plexus-utils/apidocs/org/codehaus/plexus/util/AbstractScanner.html#DEFAULTEXCLUDES&gt;</description>
+ </parameter>
+ <parameter>
+ <name>archive</name>
+ <type>org.apache.maven.archiver.MavenArchiveConfiguration</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>The archive configuration to use. See Maven Archiver Reference &lt;http://maven.apache.org/shared/maven-archiver/index.html&gt;.</description>
+ </parameter>
+ <parameter>
+ <name>classifier</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Classifier to use for test-jar.</description>
+ </parameter>
+ <parameter>
+ <name>detectMultiReleaseJar</name>
+ <type>boolean</type>
+ <since>3.4.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>If the JAR contains the META-INF/versions directory it will be detected as a multi-release JAR file (&quot;MRJAR&quot;), adding the Multi-Release: true attribute to the main section of the JAR MANIFEST.MF.</description>
+ </parameter>
+ <parameter>
+ <name>excludes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>finalName</name>
+ <type>java.lang.String</type>
+ <required>false</required>
+ <editable>false</editable>
+ <description>Name of the generated JAR.</description>
+ </parameter>
+ <parameter>
+ <name>forceCreation</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Require the jar plugin to build a new JAR even if none of the contents appear to have changed. By default, this plugin looks to see if the output jar exists and inputs have not changed. If these conditions are true, the plugin skips creation of the jar. This does not work when other plugins, like the maven-shade-plugin, are configured to post-process the jar. This plugin can not detect the post-processing, and so leaves the post-processed jar in place. This can lead to failures when those plugins do not expect to find their own output as an input. Set this parameter to true to avoid these problems by forcing this plugin to recreate the jar every time.
+Starting with 3.0.0 the property has been renamed from jar.forceCreation to maven.jar.forceCreation.</description>
+ </parameter>
+ <parameter>
+ <name>includes</name>
+ <type>java.lang.String[]</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>List of files to include. Specified as fileset patterns which are relative to the input directory whose contents is being packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the generated JAR.</description>
+ </parameter>
+ <parameter>
+ <name>outputTimestamp</name>
+ <type>java.lang.String</type>
+ <since>3.2.0</since>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended offset date-time (e.g. in UTC such as &apos;2011-12-03T10:15:30Z&apos; or with an offset &apos;2019-10-05T20:37:42+06:00&apos;), or as an int representing seconds since the epoch (like SOURCE_DATE_EPOCH &lt;https://reproducible-builds.org/docs/source-date-epoch/&gt;).</description>
+ </parameter>
+ <parameter>
+ <name>project</name>
+ <type>org.apache.maven.project.MavenProject</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The org.apache.maven.project.MavenProject.</description>
+ </parameter>
+ <parameter>
+ <name>session</name>
+ <type>org.apache.maven.execution.MavenSession</type>
+ <required>true</required>
+ <editable>false</editable>
+ <description>The org.apache.maven.execution.MavenSession.</description>
+ </parameter>
+ <parameter>
+ <name>skip</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Set this to true to bypass test-jar generation. Its use is NOT RECOMMENDED, but quite convenient on occasion.</description>
+ </parameter>
+ <parameter>
+ <name>skipIfEmpty</name>
+ <type>boolean</type>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Skip creating empty archives.</description>
+ </parameter>
+ <parameter>
+ <name>testClassesDirectory</name>
+ <type>java.io.File</type>
+ <required>true</required>
+ <editable>true</editable>
+ <description>Directory containing the test classes and resource files that should be packaged into the JAR.</description>
+ </parameter>
+ <parameter>
+ <name>useDefaultManifestFile</name>
+ <type>boolean</type>
+ <deprecated>For version 3.0.0 this parameter is only defined here to break the build if you use it!</deprecated>
+ <required>false</required>
+ <editable>true</editable>
+ <description>Using this property will fail your build cause it has been removed from the plugin configuration. See the Major Version Upgrade to version 3.0.0 &lt;https://maven.apache.org/plugins/maven-jar-plugin/&gt; for the plugin.</description>
+ </parameter>
+ </parameters>
+ <configuration>
+ <addDefaultExcludes implementation="boolean" default-value="true"/>
+ <classifier implementation="java.lang.String" default-value="tests"/>
+ <detectMultiReleaseJar implementation="boolean" default-value="true">${maven.jar.detectMultiReleaseJar}</detectMultiReleaseJar>
+ <finalName implementation="java.lang.String" default-value="${project.build.finalName}"/>
+ <forceCreation implementation="boolean" default-value="false">${maven.jar.forceCreation}</forceCreation>
+ <outputDirectory implementation="java.io.File" default-value="${project.build.directory}"/>
+ <outputTimestamp implementation="java.lang.String" default-value="${project.build.outputTimestamp}"/>
+ <project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
+ <session implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
+ <skip implementation="boolean">${maven.test.skip}</skip>
+ <skipIfEmpty implementation="boolean" default-value="false"/>
+ <testClassesDirectory implementation="java.io.File" default-value="${project.build.testOutputDirectory}"/>
+ <useDefaultManifestFile implementation="boolean" default-value="false">${jar.useDefaultManifestFile}</useDefaultManifestFile>
+ </configuration>
+ <requirements>
+ <requirement>
+ <role>java.util.Map</role>
+ <field-name>archivers</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.project.MavenProjectHelper</role>
+ <field-name>projectHelper</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.toolchain.ToolchainManager</role>
+ <field-name>toolchainManager</field-name>
+ </requirement>
+ <requirement>
+ <role>org.apache.maven.plugins.jar.ToolchainsJdkSpecification</role>
+ <field-name>toolchainsJdkSpecification</field-name>
+ </requirement>
+ </requirements>
+ </mojo>
+ </mojos>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <type>jar</type>
+ <version>4.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-xml</artifactId>
+ <type>jar</type>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-interpolation</artifactId>
+ <type>jar</type>
+ <version>1.28</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>file-management</artifactId>
+ <type>jar</type>
+ <version>3.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <type>jar</type>
+ <version>2.16.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-archiver</artifactId>
+ <type>jar</type>
+ <version>3.6.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-archiver</artifactId>
+ <type>jar</type>
+ <version>4.9.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-io</artifactId>
+ <type>jar</type>
+ <version>3.5.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.tukaani</groupId>
+ <artifactId>xz</artifactId>
+ <type>jar</type>
+ <version>1.9</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <type>jar</type>
+ <version>1.26.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <type>jar</type>
+ <version>3.14.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <type>jar</type>
+ <version>1.16.1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ <type>jar</type>
+ <version>1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <type>jar</type>
+ <version>1.7.36</version>
+ </dependency>
+ </dependencies>
+</plugin>
diff -urEbwBN maven-jar-plugin-3.4.2.orig/src/main/java/org/apache/maven/plugins/maven_jar_plugin/HelpMojo.java maven-jar-plugin-3.4.2/src/main/java/org/apache/maven/plugins/maven_jar_plugin/HelpMojo.java
--- maven-jar-plugin-3.4.2.orig/src/main/java/org/apache/maven/plugins/maven_jar_plugin/HelpMojo.java 1970-01-01 01:00:00.000000000 +0100
+++ maven-jar-plugin-3.4.2/src/main/java/org/apache/maven/plugins/maven_jar_plugin/HelpMojo.java 2025-06-06 17:25:06.596757776 +0200
@@ -0,0 +1,448 @@
+package org.apache.maven.plugins.maven_jar_plugin;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Display help information on maven-jar-plugin.<br>
+ * Call <code>mvn jar:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</code> to display parameter details.
+ * @author maven-plugin-tools
+ */
+@Mojo( name = "help", requiresProject = false, threadSafe = true )
+public class HelpMojo
+ extends AbstractMojo
+{
+ /**
+ * If <code>true</code>, display all settable properties for each goal.
+ *
+ */
+ @Parameter( property = "detail", defaultValue = "false" )
+ private boolean detail;
+
+ /**
+ * The name of the goal for which to show help. If unspecified, all goals will be displayed.
+ *
+ */
+ @Parameter( property = "goal" )
+ private java.lang.String goal;
+
+ /**
+ * The maximum length of a display line, should be positive.
+ *
+ */
+ @Parameter( property = "lineLength", defaultValue = "80" )
+ private int lineLength;
+
+ /**
+ * The number of spaces per indentation level, should be positive.
+ *
+ */
+ @Parameter( property = "indentSize", defaultValue = "2" )
+ private int indentSize;
+
+ // /META-INF/maven/<groupId>/<artifactId>/plugin-help.xml
+ private static final String PLUGIN_HELP_PATH =
+ "/META-INF/maven/org.apache.maven.plugins/maven-jar-plugin/plugin-help.xml";
+
+ private static final int DEFAULT_LINE_LENGTH = 80;
+
+ private Document build()
+ throws MojoExecutionException
+ {
+ getLog().debug( "load plugin-help.xml: " + PLUGIN_HELP_PATH );
+ try ( InputStream is = getClass().getResourceAsStream( PLUGIN_HELP_PATH ) )
+ {
+ if ( is == null )
+ {
+ throw new MojoExecutionException( "Could not find plugin descriptor at " + PLUGIN_HELP_PATH );
+ }
+ DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ return dBuilder.parse( is );
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( e.getMessage(), e );
+ }
+ catch ( ParserConfigurationException e )
+ {
+ throw new MojoExecutionException( e.getMessage(), e );
+ }
+ catch ( SAXException e )
+ {
+ throw new MojoExecutionException( e.getMessage(), e );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void execute()
+ throws MojoExecutionException
+ {
+ if ( lineLength <= 0 )
+ {
+ getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
+ lineLength = DEFAULT_LINE_LENGTH;
+ }
+ if ( indentSize <= 0 )
+ {
+ getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
+ indentSize = 2;
+ }
+
+ Document doc = build();
+
+ StringBuilder sb = new StringBuilder();
+ Node plugin = getSingleChild( doc, "plugin" );
+
+
+ String name = getValue( plugin, "name" );
+ String version = getValue( plugin, "version" );
+ String id = getValue( plugin, "groupId" ) + ":" + getValue( plugin, "artifactId" ) + ":" + version;
+ if ( isNotEmpty( name ) && !name.contains( id ) )
+ {
+ append( sb, name + " " + version, 0 );
+ }
+ else
+ {
+ if ( isNotEmpty( name ) )
+ {
+ append( sb, name, 0 );
+ }
+ else
+ {
+ append( sb, id, 0 );
+ }
+ }
+ append( sb, getValue( plugin, "description" ), 1 );
+ append( sb, "", 0 );
+
+ //<goalPrefix>plugin</goalPrefix>
+ String goalPrefix = getValue( plugin, "goalPrefix" );
+
+ Node mojos1 = getSingleChild( plugin, "mojos" );
+
+ List<Node> mojos = findNamedChild( mojos1, "mojo" );
+
+ if ( goal == null || goal.length() <= 0 )
+ {
+ append( sb, "This plugin has " + mojos.size() + ( mojos.size() > 1 ? " goals:" : " goal:" ), 0 );
+ append( sb, "", 0 );
+ }
+
+ for ( Node mojo : mojos )
+ {
+ writeGoal( sb, goalPrefix, (Element) mojo );
+ }
+
+ if ( getLog().isInfoEnabled() )
+ {
+ getLog().info( sb.toString() );
+ }
+ }
+
+
+ private static boolean isNotEmpty( String string )
+ {
+ return string != null && string.length() > 0;
+ }
+
+ private static String getValue( Node node, String elementName )
+ throws MojoExecutionException
+ {
+ return getSingleChild( node, elementName ).getTextContent();
+ }
+
+ private static Node getSingleChild( Node node, String elementName )
+ throws MojoExecutionException
+ {
+ List<Node> namedChild = findNamedChild( node, elementName );
+ if ( namedChild.isEmpty() )
+ {
+ throw new MojoExecutionException( "Could not find " + elementName + " in plugin-help.xml" );
+ }
+ if ( namedChild.size() > 1 )
+ {
+ throw new MojoExecutionException( "Multiple " + elementName + " in plugin-help.xml" );
+ }
+ return namedChild.get( 0 );
+ }
+
+ private static List<Node> findNamedChild( Node node, String elementName )
+ {
+ List<Node> result = new ArrayList<Node>();
+ NodeList childNodes = node.getChildNodes();
+ for ( int i = 0; i < childNodes.getLength(); i++ )
+ {
+ Node item = childNodes.item( i );
+ if ( elementName.equals( item.getNodeName() ) )
+ {
+ result.add( item );
+ }
+ }
+ return result;
+ }
+
+ private static Node findSingleChild( Node node, String elementName )
+ throws MojoExecutionException
+ {
+ List<Node> elementsByTagName = findNamedChild( node, elementName );
+ if ( elementsByTagName.isEmpty() )
+ {
+ return null;
+ }
+ if ( elementsByTagName.size() > 1 )
+ {
+ throw new MojoExecutionException( "Multiple " + elementName + "in plugin-help.xml" );
+ }
+ return elementsByTagName.get( 0 );
+ }
+
+ private void writeGoal( StringBuilder sb, String goalPrefix, Element mojo )
+ throws MojoExecutionException
+ {
+ String mojoGoal = getValue( mojo, "goal" );
+ Node configurationElement = findSingleChild( mojo, "configuration" );
+ Node description = findSingleChild( mojo, "description" );
+ if ( goal == null || goal.length() <= 0 || mojoGoal.equals( goal ) )
+ {
+ append( sb, goalPrefix + ":" + mojoGoal, 0 );
+ Node deprecated = findSingleChild( mojo, "deprecated" );
+ if ( ( deprecated != null ) && isNotEmpty( deprecated.getTextContent() ) )
+ {
+ append( sb, "Deprecated. " + deprecated.getTextContent(), 1 );
+ if ( detail && description != null )
+ {
+ append( sb, "", 0 );
+ append( sb, description.getTextContent(), 1 );
+ }
+ }
+ else if ( description != null )
+ {
+ append( sb, description.getTextContent(), 1 );
+ }
+ append( sb, "", 0 );
+
+ if ( detail )
+ {
+ Node parametersNode = getSingleChild( mojo, "parameters" );
+ List<Node> parameters = findNamedChild( parametersNode, "parameter" );
+ append( sb, "Available parameters:", 1 );
+ append( sb, "", 0 );
+
+ for ( Node parameter : parameters )
+ {
+ writeParameter( sb, parameter, configurationElement );
+ }
+ }
+ }
+ }
+
+ private void writeParameter( StringBuilder sb, Node parameter, Node configurationElement )
+ throws MojoExecutionException
+ {
+ String parameterName = getValue( parameter, "name" );
+ String parameterDescription = getValue( parameter, "description" );
+
+ Element fieldConfigurationElement = null;
+ if ( configurationElement != null )
+ {
+ fieldConfigurationElement = (Element) findSingleChild( configurationElement, parameterName );
+ }
+
+ String parameterDefaultValue = "";
+ if ( fieldConfigurationElement != null && fieldConfigurationElement.hasAttribute( "default-value" ) )
+ {
+ parameterDefaultValue = " (Default: " + fieldConfigurationElement.getAttribute( "default-value" ) + ")";
+ }
+ append( sb, parameterName + parameterDefaultValue, 2 );
+ Node deprecated = findSingleChild( parameter, "deprecated" );
+ if ( ( deprecated != null ) && isNotEmpty( deprecated.getTextContent() ) )
+ {
+ append( sb, "Deprecated. " + deprecated.getTextContent(), 3 );
+ append( sb, "", 0 );
+ }
+ if ( isNotEmpty( parameterDescription ) ) {
+ append( sb, parameterDescription, 3 );
+ }
+ if ( "true".equals( getValue( parameter, "required" ) ) )
+ {
+ append( sb, "Required: Yes", 3 );
+ }
+ if ( ( fieldConfigurationElement != null ) && isNotEmpty( fieldConfigurationElement.getTextContent() ) )
+ {
+ String property = getPropertyFromExpression( fieldConfigurationElement.getTextContent() );
+ append( sb, "User property: " + property, 3 );
+ }
+
+ append( sb, "", 0 );
+ }
+
+ /**
+ * <p>Repeat a String <code>n</code> times to form a new string.</p>
+ *
+ * @param str String to repeat
+ * @param repeat number of times to repeat str
+ * @return String with repeated String
+ * @throws NegativeArraySizeException if <code>repeat &lt; 0</code>
+ * @throws NullPointerException if str is <code>null</code>
+ */
+ private static String repeat( String str, int repeat )
+ {
+ StringBuilder buffer = new StringBuilder( repeat * str.length() );
+
+ for ( int i = 0; i < repeat; i++ )
+ {
+ buffer.append( str );
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Append a description to the buffer by respecting the indentSize and lineLength parameters.
+ * <b>Note</b>: The last character is always a new line.
+ *
+ * @param sb The buffer to append the description, not <code>null</code>.
+ * @param description The description, not <code>null</code>.
+ * @param indent The base indentation level of each line, must not be negative.
+ */
+ private void append( StringBuilder sb, String description, int indent )
+ {
+ for ( String line : toLines( description, indent, indentSize, lineLength ) )
+ {
+ sb.append( line ).append( '\n' );
+ }
+ }
+
+ /**
+ * Splits the specified text into lines of convenient display length.
+ *
+ * @param text The text to split into lines, must not be <code>null</code>.
+ * @param indent The base indentation level of each line, must not be negative.
+ * @param indentSize The size of each indentation, must not be negative.
+ * @param lineLength The length of the line, must not be negative.
+ * @return The sequence of display lines, never <code>null</code>.
+ * @throws NegativeArraySizeException if <code>indent &lt; 0</code>
+ */
+ private static List<String> toLines( String text, int indent, int indentSize, int lineLength )
+ {
+ List<String> lines = new ArrayList<String>();
+
+ String ind = repeat( "\t", indent );
+
+ String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
+
+ for ( String plainLine : plainLines )
+ {
+ toLines( lines, ind + plainLine, indentSize, lineLength );
+ }
+
+ return lines;
+ }
+
+ /**
+ * Adds the specified line to the output sequence, performing line wrapping if necessary.
+ *
+ * @param lines The sequence of display lines, must not be <code>null</code>.
+ * @param line The line to add, must not be <code>null</code>.
+ * @param indentSize The size of each indentation, must not be negative.
+ * @param lineLength The length of the line, must not be negative.
+ */
+ private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
+ {
+ int lineIndent = getIndentLevel( line );
+ StringBuilder buf = new StringBuilder( 256 );
+
+ String[] tokens = line.split( " +" );
+
+ for ( String token : tokens )
+ {
+ if ( buf.length() > 0 )
+ {
+ if ( buf.length() + token.length() >= lineLength )
+ {
+ lines.add( buf.toString() );
+ buf.setLength( 0 );
+ buf.append( repeat( " ", lineIndent * indentSize ) );
+ }
+ else
+ {
+ buf.append( ' ' );
+ }
+ }
+
+ for ( int j = 0; j < token.length(); j++ )
+ {
+ char c = token.charAt( j );
+ if ( c == '\t' )
+ {
+ buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
+ }
+ else if ( c == '\u00A0' )
+ {
+ buf.append( ' ' );
+ }
+ else
+ {
+ buf.append( c );
+ }
+ }
+ }
+ lines.add( buf.toString() );
+ }
+
+ /**
+ * Gets the indentation level of the specified line.
+ *
+ * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
+ * @return The indentation level of the line.
+ */
+ private static int getIndentLevel( String line )
+ {
+ int level = 0;
+ for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
+ {
+ level++;
+ }
+ for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
+ {
+ if ( line.charAt( i ) == '\t' )
+ {
+ level++;
+ break;
+ }
+ }
+ return level;
+ }
+
+ private static String getPropertyFromExpression( String expression )
+ {
+ if ( expression != null && expression.startsWith( "${" ) && expression.endsWith( "}" )
+ && !expression.substring( 2 ).contains( "${" ) )
+ {
+ // expression="${xxx}" -> property="xxx"
+ return expression.substring( 2, expression.length() - 1 );
+ }
+ // no property can be extracted
+ return null;
+ }
+}