diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index a81c847..e3af3a7 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -5,7 +5,6 @@ name: Java CI with Maven
on:
push:
- branches: [ develop ]
pull_request:
branches: [ develop ]
@@ -16,9 +15,13 @@ jobs:
steps:
- uses: actions/checkout@v2
- - name: Set up JDK 1.8
- uses: actions/setup-java@v1
+ - name: Set up JDK
+ uses: actions/setup-java@v3
with:
- java-version: 1.8
+ java-version-file: .java-version
+ distribution: 'temurin'
+ cache: 'maven'
+ - name: Print Maven version
+ run: mvn --version
- name: Build with Maven
- run: mvn -B package --file pom.xml
+ run: mvn -B verify --file pom.xml -PintegrationTest
diff --git a/.java-version b/.java-version
new file mode 100644
index 0000000..b4de394
--- /dev/null
+++ b/.java-version
@@ -0,0 +1 @@
+11
diff --git a/README.md b/README.md
index 1ed2c87..720524e 100644
--- a/README.md
+++ b/README.md
@@ -2,14 +2,17 @@
You can use this Maven plugin to generate XML descriptors for FirstSpirit modules.
-Make sure you use maven 3.1.x or newer when integrating this plugin into your workspace.
+Make sure you use Maven 3.3 or newer when integrating this plugin into your workspace.
+
+**Attention:** Due to internal changes in Maven 3.8.8 or 3.9.0 and newer, incomplete module.xml files and
+FirstSpirit modules may be created with the old `dependencyToXML` goal. Therefore, you should migrate to
+plug-in version 2.0.0 and the new `prepare` goal as quickly as possible.
# Getting started
## Maven Dependency [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.monday-consulting.maven.plugins/fsm-maven-plugin/badge.svg?style=flat)](http://mvnrepository.com/artifact/com.monday-consulting.maven.plugins/fsm-maven-plugin)
-We published our plugin to the maven central repository.
-You could include it into your workspace with the following maven dependency:
+The FSM Maven plugin is published on Maven Central:
```
@@ -19,107 +22,47 @@ You could include it into your workspace with the following maven dependency:
```
+## Maven Goals
+
+As of version 2.0.0, the recommended Maven goal is `prepare`.
+
+- `prepare`
+- `dependencyToXML` _(deprecated)_
+- `attachFSM` _(deprecated)_
+
## Plugin Configuration
-* You have to configure the plugin with an prototype.xml, the config.xml and a target.
-* Your plugin configuration should look like this:
+Two things are important for the configuration of the plugin:
+- `configXml` defines a list of modules for which dependencies are collected. These are then inserted into the prototype
+`module.xml`.
+- `prototypeXml` is the template for the `module.xml` to be generated. This is completed with all dependencies.
+
+Full examples can be found in the integration tests, e.g. [prepare-example](./src/it/prepare-example).
```
com.monday-consulting.maven.plugins
fsm-maven-plugin
- ${basedir}/target/extra-resources/prototype.module.xml
${basedir}/target/extra-resources/fsm-plugin.xml
- ${basedir}/target/extra-resources/module.xml
+ ${basedir}/target/extra-resources/prototype.module.xml
- dependencyToXML
+ prepare-module
package
- dependencyToXML
+ prepare
```
-## Prototype XML
-
-* This is your prototype FirstSpirit module descriptor which will be consumed by this plugin to generate your working module.xml
-* In this file you have to configure your FirstSpirit module components (i.e. project and web components).
-* Your prototype XML could look like this:
-
-```
-
- Monday Webforms
- ${project.version}
- Monday Webforms Form Editor
- Monday Consulting GmbH
-
-
-
- MONDAY_FORMEDITOR
- Monday Webforms editor component
- de.espirit.firstspirit.module.GadgetSpecification
-
- com.monday.webforms.editor.gom.GomFormEditor
- com.monday.webforms.editor.gadgets.FormEditorSwingGadgetFactory
- com.monday.webforms.editor.gadgets.FormValueEngineerFactory
-
-
-
- files/
- webforms-editor-resources
-
-
-
-
- Monday Webforms Resources
- Monday Webforms project resources
- com.monday.webforms.admin.project.WebformsProjectApp
-
- files/
- webforms-admin-resources
-
-
-
-
- Monday Webforms WebApp
- Monday Webforms FIRSTspirit integration.
- com.monday.webforms.admin.webapp.WebAppConfiguration
- com.monday.webforms.admin.WebformsWebApp
- web.xml
-
- webforms-admin-resources
-
-
- webforms-webapp-resources
-
-
-
-
- Monday Webforms Analytics Backend
- Monday Webforms Analytics Backend FIRSTspirit integration.
- com.monday.webforms.admin.analytics.backend.WebAppConfiguration
- com.monday.webforms.admin.WebformsWebApp
- external/backend/WEB-INF/web.xml
-
- webforms-admin-resources
-
-
- webforms-backend-libs
-
-
-
-
-```
-
## Config XML
-* In your config.xml you have to configure which folder or artifact should be included in your module descriptor.
-* Your config.xml could look like this:
+Here you configure for which modules dependencies should be collected. The identifier from `dependencyTagValueInXml`
+can then be used in the `module.xml` prototype.
```
@@ -130,9 +73,8 @@ You could include it into your workspace with the following maven dependency:
- com.monday.webforms.firstspirit:webforms-webapp:war
- lib/
- webforms-webapp-resources
+ org.example:example-webapp:war
+ example-webapp-resources
module
WEB-INF/web.xml
@@ -145,368 +87,71 @@ You could include it into your workspace with the following maven dependency:
-
- com.monday.webforms.analytics:webforms-reporting-webapp:war:${monday.webforms.backend.version}
- external/reporting/WEB-INF/lib/
- webforms-reporting-libs
- module
-
- external/reporting/
- WEB-INF/web.xml
-
- **
-
-
- META-INF
- WEB-INF/lib/
-
-
-
```
This example includes everything in the WEB-INF folder but excludes explicitly the folders WEB-INF/lib and WEB-INF/classes.
-## Generated module XML
+## Prototype XML
-* A module.xml file generated by this plugin could look like this:
+This is the prototype FirstSpirit module descriptor which will be consumed by this plugin to generate the working
+`module.xml`. We recommend filtering this prototype beforehand with the Maven Resources plugin so that all variables
+(e.g. `${project.version}`) are replaced.
+
+This is basically a `module.xml` with missing (web-)resources. Here, `identifier` is used
+instead to refer to entries from the `configXml`.
```
- Monday Webforms
- 5.5.0-SNAPSHOT
- Monday Webforms Form Editor
- Monday Consulting GmbH
-
-
- MONDAY_FORMEDITOR
- Monday Webforms editor component
- de.espirit.firstspirit.module.GadgetSpecification
-
- com.monday.webforms.editor.gom.GomFormEditor
- com.monday.webforms.editor.gadgets.FormEditorSwingGadgetFactory
- com.monday.webforms.editor.gadgets.FormValueEngineerFactory
-
-
-
- files/
- lib/webforms-common-5.5.0-SNAPSHOT.jar
- lib/webforms-shared-5.5.0-SNAPSHOT.jar
- lib/commons-io-1.3.2.jar
- lib/rhino-1.7.7.1.jar
- lib/jPod-5.5.1.jar
- lib/iscwt-5.5.jar
- lib/isfreetype-5.5.jar
- lib/isnativec-5.5.jar
- lib/jai-core-1.1.3.jar
- lib/jai-codec-1.1.3.jar
- lib/isrt-4.10.jar
- lib/jbig2-5.5.1.jar
- lib/license4j-1.6.jar
- lib/webforms-gui-5.5.0-SNAPSHOT.jar
- lib/webforms-admin-5.5.0-SNAPSHOT.jar
- lib/designgridlayout-1.1.jar
- lib/swing-layout-1.0.2.jar
- lib/monday-common-3.1.1.jar
- lib/javax.mail-api-1.4.4.jar
- lib/activation-1.1.1.jar
- lib/jna-4.1.0.jar
- lib/fs-access-5.2.181206.jar
- lib/slf4j-api-1.6.4.jar
- lib/gson-2.8.2.jar
- lib/commons-lang3-3.7.jar
- lib/rsyntaxtextarea-2.6.1.jar
- lib/webforms-editor-5.5.0-SNAPSHOT.jar
-
-
-
- Monday Webforms WebApp
- Monday Webforms FIRSTspirit integration.
- com.monday.webforms.admin.webapp.WebAppConfiguration
- com.monday.webforms.admin.WebformsWebApp
- web.xml
-
- lib/webforms-gui-5.5.0-SNAPSHOT.jar
- lib/rsyntaxtextarea-2.6.1.jar
- lib/webforms-common-5.5.0-SNAPSHOT.jar
- lib/webforms-shared-5.5.0-SNAPSHOT.jar
- lib/commons-io-1.3.2.jar
- lib/slf4j-api-1.6.4.jar
- lib/rhino-1.7.7.1.jar
- lib/gson-2.8.2.jar
- lib/jPod-5.5.1.jar
- lib/iscwt-5.5.jar
- lib/isfreetype-5.5.jar
- lib/isnativec-5.5.jar
- lib/jna-4.1.0.jar
- lib/jai-core-1.1.3.jar
- lib/jai-codec-1.1.3.jar
- lib/isrt-4.10.jar
- lib/jbig2-5.5.1.jar
- lib/monday-common-3.1.1.jar
- lib/javax.mail-api-1.4.4.jar
- lib/activation-1.1.1.jar
- lib/fs-access-5.2.181206.jar
- lib/license4j-1.6.jar
- lib/designgridlayout-1.1.jar
- lib/swing-layout-1.0.2.jar
- lib/webforms-executables-5.5.0-SNAPSHOT.jar
- lib/webforms-admin-5.5.0-SNAPSHOT.jar
-
-
- lib/webforms-webapp-lib-5.5.0-SNAPSHOT.jar
- lib/fs-access-5.2.181206.jar
- lib/webforms-common-5.5.0-SNAPSHOT.jar
- lib/jPod-5.5.1.jar
- lib/iscwt-5.5.jar
- lib/isfreetype-5.5.jar
- lib/isnativec-5.5.jar
- lib/jna-4.1.0.jar
- lib/jai-core-1.1.3.jar
- lib/jai-codec-1.1.3.jar
- lib/isrt-4.10.jar
- lib/jbig2-5.5.1.jar
- lib/webforms-spring-5.5.0-SNAPSHOT.jar
- lib/jcl-over-slf4j-1.6.4.jar
- lib/webforms-shared-5.5.0-SNAPSHOT.jar
- lib/webforms-executables-5.5.0-SNAPSHOT.jar
- lib/monday-common-3.1.1.jar
- lib/webforms-backend-api-client-2.2.2.jar
- lib/webforms-backend-common-2.2.2.jar
- lib/webforms-backend-api-model-2.2.2.jar
- lib/annotations-13.0.jar
- lib/jackson-core-2.8.11.jar
- lib/jackson-databind-2.8.11.2.jar
- lib/jackson-annotations-2.8.0.jar
- lib/jai-imageio-core-1.3.1.jar
- lib/commons-lang3-3.7.jar
- lib/taglibs-standard-impl-1.2.5.jar
- lib/commons-beanutils-1.9.3.jar
- lib/commons-collections-3.2.2.jar
- lib/commons-io-1.3.2.jar
- lib/easystream-1.2.15.jar
- lib/slf4j-api-1.6.4.jar
- lib/slf4j-log4j12-1.6.4.jar
- lib/log4j-1.2.17.jar
- lib/javax.mail-api-1.4.4.jar
- lib/activation-1.1.1.jar
- lib/rhino-1.7.7.1.jar
- lib/cglib-nodep-3.2.7.jar
- lib/jcaptcha-2.0-alpha-1.jar
- lib/filters-2.0.235.jar
- lib/jcaptcha-api-2.0-alpha-1.jar
- lib/spring-context-4.3.22.RELEASE.jar
- lib/spring-aop-4.3.22.RELEASE.jar
- lib/spring-expression-4.3.22.RELEASE.jar
- lib/commons-fileupload-1.3.1.jar
- lib/commons-validator-1.6.jar
- lib/commons-digester-1.8.1.jar
- lib/spring-web-4.3.22.RELEASE.jar
- lib/spring-webmvc-4.3.22.RELEASE.jar
- lib/spring-core-4.3.22.RELEASE.jar
- lib/spring-context-support-4.3.22.RELEASE.jar
- lib/license4j-1.6.jar
- lib/poi-ooxml-3.17.jar
- lib/poi-ooxml-schemas-3.17.jar
- lib/xmlbeans-2.6.0.jar
- lib/curvesapi-1.04.jar
- lib/owasp-java-html-sanitizer-20180219.1.jar
- lib/guava-11.0.2.jar
- lib/poi-3.17.jar
- lib/commons-codec-1.6.jar
- lib/commons-collections4-4.1.jar
- lib/spring-beans-4.3.22.RELEASE.jar
- lib/javax.servlet.jsp.jstl-api-1.2.2.jar
- lib/tika-core-1.17.jar
- lib/gson-2.8.2.jar
- lib/commonmark-0.12.1.jar
- lib/commonmark-ext-gfm-tables-0.12.1.jar
- lib/commonmark-ext-link-attributes-1.0.1.jar
- lib/mapdb-1.0.6.jar
- lib/freemarker-2.3.28.jar
- lib/imgscalr-lib-4.2.jar
- lib/httpclient-4.4.jar
- lib/httpcore-4.4.jar
- lib/commons-logging-1.1.3.jar
- WEB-INF/webforms-analytics.properties
- WEB-INF/webforms-mail.properties
- WEB-INF/webforms-network.properties
- WEB-INF/webforms-license.txt
- WEB-INF/webforms-license.properties
- WEB-INF/webforms-pdf.properties
- WEB-INF/webforms-connection.properties
- WEB-INF/templates/pageBreak.jsp
- WEB-INF/templates/layout.jsp
- WEB-INF/templates/error.jsp
- WEB-INF/templates/checkBoxGroup.jsp
- WEB-INF/templates/fileUpload.jsp
- WEB-INF/templates/captcha.jsp
- WEB-INF/templates/success.jsp
- WEB-INF/templates/uploadSizeExceeded.jsp
- WEB-INF/templates/exit.jsp
- WEB-INF/templates/textArea.jsp
- WEB-INF/templates/pdf.jsp
- WEB-INF/templates/redirect.jsp
- WEB-INF/templates/radioGroup.jsp
- WEB-INF/templates/summary.jsp
- WEB-INF/templates/condition.jsp
- WEB-INF/templates/default.jsp
- WEB-INF/templates/button.jsp
- WEB-INF/templates/webform.jsp
- WEB-INF/templates/passwordField.jsp
- WEB-INF/templates/paragraph.jsp
- WEB-INF/templates/hiddenField.jsp
- WEB-INF/templates/methodNotSupported.jsp
- WEB-INF/templates/inputField.jsp
- WEB-INF/templates/optin.jsp
- WEB-INF/templates/calculatedValue.jsp
- WEB-INF/templates/comboBox.jsp
- WEB-INF/templates/sessionExpired.jsp
- WEB-INF/templates/invalidLicense.jsp
- WEB-INF/webforms-excel.properties
- WEB-INF/log4j.properties
- WEB-INF/spring/webforms-views.xml
- WEB-INF/spring/webforms-resourcebundle.xml
- WEB-INF/spring/webforms-mail.xml
- WEB-INF/spring/webforms-actions.xml
- WEB-INF/spring/webforms-analytics.xml
- WEB-INF/spring/webforms-network.xml
- WEB-INF/spring/webforms-application.xml
- WEB-INF/spring/webforms-services.xml
- WEB-INF/spring/webforms-license.xml
- WEB-INF/spring/webforms-connection.xml
- WEB-INF/spring/webforms-controllers.xml
- WEB-INF/spring/webforms-captcha.xml
-
-
-
- Monday Webforms Analytics Backend
- 2.2.2
- Monday Webforms Analytics Backend FIRSTspirit integration.
- com.monday.webforms.admin.analytics.backend.WebAppConfiguration
- com.monday.webforms.admin.WebformsWebApp
- external/backend/WEB-INF/web.xml
-
- lib/webforms-gui-5.5.0-SNAPSHOT.jar
- lib/rsyntaxtextarea-2.6.1.jar
- lib/webforms-common-5.5.0-SNAPSHOT.jar
- lib/webforms-shared-5.5.0-SNAPSHOT.jar
- lib/commons-io-1.3.2.jar
- lib/slf4j-api-1.6.4.jar
- lib/rhino-1.7.7.1.jar
- lib/gson-2.8.2.jar
- lib/jPod-5.5.1.jar
- lib/iscwt-5.5.jar
- lib/isfreetype-5.5.jar
- lib/isnativec-5.5.jar
- lib/jna-4.1.0.jar
- lib/jai-core-1.1.3.jar
- lib/jai-codec-1.1.3.jar
- lib/isrt-4.10.jar
- lib/jbig2-5.5.1.jar
- lib/monday-common-3.1.1.jar
- lib/javax.mail-api-1.4.4.jar
- lib/activation-1.1.1.jar
- lib/fs-access-5.2.181206.jar
- lib/license4j-1.6.jar
- lib/designgridlayout-1.1.jar
- lib/swing-layout-1.0.2.jar
- lib/webforms-executables-5.5.0-SNAPSHOT.jar
- lib/webforms-admin-5.5.0-SNAPSHOT.jar
-
-
- external/backend/WEB-INF/lib/webforms-backend-webapp-lib-2.2.2.jar
- external/backend/WEB-INF/lib/webforms-backend-common-2.2.2.jar
- external/backend/WEB-INF/lib/webforms-backend-api-model-2.2.2.jar
- external/backend/WEB-INF/lib/jackson-annotations-2.8.0.jar
- external/backend/WEB-INF/lib/monday-common-3.1.0.jar
- external/backend/WEB-INF/lib/freemarker-2.3.28.jar
- external/backend/WEB-INF/lib/commons-csv-1.5.jar
- external/backend/WEB-INF/lib/commons-lang3-3.7.jar
- external/backend/WEB-INF/lib/poi-3.17.jar
- external/backend/WEB-INF/lib/commons-collections4-4.1.jar
- external/backend/WEB-INF/lib/poi-ooxml-3.17.jar
- external/backend/WEB-INF/lib/poi-ooxml-schemas-3.17.jar
- external/backend/WEB-INF/lib/xmlbeans-2.6.0.jar
- external/backend/WEB-INF/lib/stax-api-1.0.1.jar
- external/backend/WEB-INF/lib/curvesapi-1.04.jar
- external/backend/WEB-INF/lib/xbean-classloader-4.8.jar
- external/backend/WEB-INF/lib/spring-boot-starter-amqp-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-messaging-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-rabbit-1.7.9.RELEASE.jar
- external/backend/WEB-INF/lib/spring-amqp-1.7.9.RELEASE.jar
- external/backend/WEB-INF/lib/spring-retry-1.2.2.RELEASE.jar
- external/backend/WEB-INF/lib/http-client-1.1.1.RELEASE.jar
- external/backend/WEB-INF/lib/httpclient-4.5.6.jar
- external/backend/WEB-INF/lib/httpcore-4.4.10.jar
- external/backend/WEB-INF/lib/amqp-client-4.0.3.jar
- external/backend/WEB-INF/lib/spring-boot-starter-actuator-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-boot-actuator-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/persistence-api-1.0.2.jar
- external/backend/WEB-INF/lib/commons-math3-3.6.1.jar
- external/backend/WEB-INF/lib/gson-2.8.5.jar
- external/backend/WEB-INF/lib/annotations-13.0.jar
- external/backend/WEB-INF/lib/flyway-core-3.2.1.jar
- external/backend/WEB-INF/lib/xstream-1.4.10.jar
- external/backend/WEB-INF/lib/xmlpull-1.1.3.1.jar
- external/backend/WEB-INF/lib/xpp3_min-1.1.4c.jar
- external/backend/WEB-INF/lib/rxjava-1.3.8.jar
- external/backend/WEB-INF/lib/spring-boot-legacy-1.1.0.RELEASE.jar
- external/backend/WEB-INF/lib/spring-security-core-4.2.7.RELEASE.jar
- external/backend/WEB-INF/lib/aopalliance-1.0.jar
- external/backend/WEB-INF/lib/spring-aop-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-beans-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-context-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-core-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-expression-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-security-web-4.2.7.RELEASE.jar
- external/backend/WEB-INF/lib/spring-web-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-security-config-4.2.7.RELEASE.jar
- external/backend/WEB-INF/lib/spring-security-oauth2-2.0.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-webmvc-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/commons-codec-1.10.jar
- external/backend/WEB-INF/lib/jackson-mapper-asl-1.9.13.jar
- external/backend/WEB-INF/lib/jackson-core-asl-1.9.13.jar
- external/backend/WEB-INF/lib/spring-security-aspects-4.2.7.RELEASE.jar
- external/backend/WEB-INF/lib/slf4j-api-1.7.12.jar
- external/backend/WEB-INF/lib/spring-boot-starter-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-boot-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-boot-autoconfigure-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/snakeyaml-1.17.jar
- external/backend/WEB-INF/lib/spring-boot-starter-log4j2-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/log4j-slf4j-impl-2.7.jar
- external/backend/WEB-INF/lib/log4j-api-2.7.jar
- external/backend/WEB-INF/lib/log4j-core-2.7.jar
- external/backend/WEB-INF/lib/jcl-over-slf4j-1.7.12.jar
- external/backend/WEB-INF/lib/jul-to-slf4j-1.7.25.jar
- external/backend/WEB-INF/lib/spring-boot-starter-web-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/hibernate-validator-5.3.6.Final.jar
- external/backend/WEB-INF/lib/validation-api-1.1.0.Final.jar
- external/backend/WEB-INF/lib/jboss-logging-3.3.2.Final.jar
- external/backend/WEB-INF/lib/classmate-1.3.4.jar
- external/backend/WEB-INF/lib/jackson-databind-2.8.11.2.jar
- external/backend/WEB-INF/lib/jackson-core-2.8.11.jar
- external/backend/WEB-INF/lib/spring-boot-starter-jdbc-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-jdbc-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-tx-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/spring-boot-starter-mail-1.5.15.RELEASE.jar
- external/backend/WEB-INF/lib/spring-context-support-4.3.18.RELEASE.jar
- external/backend/WEB-INF/lib/javax.mail-1.5.6.jar
- external/backend/WEB-INF/lib/activation-1.1.jar
- external/backend/WEB-INF/lib/commons-dbcp2-2.3.0.jar
- external/backend/WEB-INF/lib/commons-pool2-2.4.3.jar
- external/backend/WEB-INF/lib/commons-logging-1.2.jar
- external/backend/WEB-INF/classes/log4j2.xml
- external/backend/WEB-INF/classes/banner.txt
- external/backend/WEB-INF/classes/application.properties
- external/backend/WEB-INF/lib-migration/spring-security-oauth2-2.0.14.RELEASE.jar
- external/backend/WEB-INF/lib-migration/spring-security-core-4.0.4.RELEASE.jar
- external/backend/WEB-INF/webforms-backend.properties
- external/backend/WEB-INF/spring/backend-custom-overrides.xml
- external/backend/WEB-INF/spring/backend-authentication.xml
- external/backend/WEB-INF/spring/backend-security.xml
-
-
-
+ My FirstSpirit Module (I)
+ ${project.version}
+ A simple example for a prototype.module.xml
+ Monday Consulting GmbH
+
+
+ MY_PUBLIC_COMPONENT
+ A FirstSpirit Gadget
+ de.espirit.firstspirit.module.GadgetSpecification
+
+ org.example.GomExampleEditor
+ org.example.gadgets.ExampleSwingGadgetFactory
+ org.example.gadgets.ExmplaeValueEngineerFactory
+
+
+
+ files/
+ my-gadget-dependencies
+
+
+
+ Example WebApp
+ Monday Webforms FIRSTspirit integration.
+ org.example.webapp.WebAppConfiguration
+ org.example.ExanokeWebApp
+ web.xml
+
+ example-webapp-config-resources
+
+
+ example-webapp-resources
+
+
+
```
+
+## Plugin output
+
+The plugin prepares the folder structure of a FirstSpirit module, which already contains the `module.xml` as well as
+`module-isolated.xml` and all required dependencies:
+
+- `target/fsm-root`
+ - `META-INF`
+ - `module.xml`
+ - `module-isolated.xml`
+ - `lib`
+ - _all JARs referenced in the module descriptor_
+
+Finally, to create the FSM archive, the Maven Assembly Plugin is required. With the help of an assembly descriptor,
+additional files (configurations, customized `web.xml`, etc.) can be added to the module. You can find examples of
+this in the integration tests: [prepare-example](./src/it/prepare-example).
diff --git a/pom.xml b/pom.xml
index 8c49753..95f2c39 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.monday-consulting.maven.plugins
fsm-maven-plugin
maven-plugin
- 1.8.2
+ 2.0.0
fsm-maven-plugin
https://www.monday-consulting.com
@@ -73,29 +73,29 @@
- 3.1.0
+ 3.3.9
UTF-8
- 1.8
- 1.8
+ 11
+ 11
3.3.9
- 1.1.0
5.9.0
3.6.4
1.6.13
1.5
- 3.3.0
- 1.6
- 3.2.0
- 3.10.1
+ 3.3.1
+ 3.1.0
+ 3.6.0
+ 3.3.1
+ 3.11.0
3.3.0
- 2.22.2
+ 3.1.2
@@ -204,6 +204,18 @@
${mavenVersion}
provided
+
+ org.apache.maven
+ maven-model
+ ${mavenVersion}
+ provided
+
+
+ org.apache.maven
+ maven-artifact
+ ${mavenVersion}
+ provided
+
org.apache.maven
maven-plugin-api
@@ -221,19 +233,9 @@
2.3.6
- org.eclipse.aether
- aether-api
- ${eclipseAetherVersion}
-
-
- org.eclipse.aether
- aether-util
- ${eclipseAetherVersion}
-
-
- org.eclipse.aether
- aether-impl
- ${eclipseAetherVersion}
+ org.apache.maven.shared
+ maven-artifact-transfer
+ 0.13.1
net.lingala.zip4j
@@ -253,6 +255,12 @@
${junit.version}
test
+
+ org.mockito
+ mockito-core
+ 4.5.1
+ test
+
@@ -305,7 +313,7 @@
org.apache.maven.plugins
maven-invoker-plugin
- 3.3.0
+ ${maven.invoker.plugin}
src/it
${project.build.directory}/it
@@ -316,6 +324,13 @@
${maven.home}/bin/mvnDebug
-->
+
+
+ org.apache.groovy
+ groovy-xml
+ 4.0.13
+
+
integration-test
diff --git a/src/it/dependency-conflict/fsm/plugin.xml b/src/it/d2xml-dependency-conflict/fsm/plugin.xml
similarity index 100%
rename from src/it/dependency-conflict/fsm/plugin.xml
rename to src/it/d2xml-dependency-conflict/fsm/plugin.xml
diff --git a/src/it/dependency-conflict/fsm/prototype.module.xml b/src/it/d2xml-dependency-conflict/fsm/prototype.module.xml
similarity index 100%
rename from src/it/dependency-conflict/fsm/prototype.module.xml
rename to src/it/d2xml-dependency-conflict/fsm/prototype.module.xml
diff --git a/src/it/dependency-conflict/pom.xml b/src/it/d2xml-dependency-conflict/pom.xml
similarity index 100%
rename from src/it/dependency-conflict/pom.xml
rename to src/it/d2xml-dependency-conflict/pom.xml
diff --git a/src/it/dependency-conflict/verify.groovy b/src/it/d2xml-dependency-conflict/verify.groovy
similarity index 64%
rename from src/it/dependency-conflict/verify.groovy
rename to src/it/d2xml-dependency-conflict/verify.groovy
index 4b690a3..807dfd0 100644
--- a/src/it/dependency-conflict/verify.groovy
+++ b/src/it/d2xml-dependency-conflict/verify.groovy
@@ -1,7 +1,9 @@
+import groovy.xml.XmlSlurper
+
def moduleXmlFile = new File(basedir, 'target/extra-resources/module.xml')
-assert moduleXmlFile.exists() : "The module.xml descriptor was not created.";
+assert moduleXmlFile.exists() : "The module.xml descriptor was not created"
def doc = new XmlSlurper().parse(moduleXmlFile)
-assert doc.version == "15.5.0" : "The module.xml version was not filtered."
+assert doc.version == "15.5.0" : "The module.xml version was not filtered"
// Verify resolved versions for guava
@@ -12,16 +14,16 @@ static def getResource(doc, mode, scope, name) {
}
}
-static def verifyResource(doc, mode, scope, version) {
+static def verifyResource(doc, mode, scope, versionPattern) {
def guava = "com.google.guava:guava"
def resource = getResource(doc, mode, scope, guava)
def resourceSize = resource.size()
assert resourceSize == 1
def resourceVersion = resource.get(0).attributes().version
- assert resourceVersion == version : "Guava version for " + mode + "-" + scope + " must be " + version
+ assert resourceVersion ==~ versionPattern: "Guava version for " + mode + "-" + scope + " must match " + versionPattern
}
-verifyResource(doc, "isolated", "module", "27.1-jre")
-verifyResource(doc, "isolated", "server", "19.0.20150826")
-verifyResource(doc, "legacy", "server", "31.1-jre")
+verifyResource(doc, "isolated", "module", /27.1-jre/)
+verifyResource(doc, "isolated", "server", /19.0.*/)
+verifyResource(doc, "legacy", "server", /31.1-jre/)
diff --git a/src/it/example/fsm/plugin.xml b/src/it/d2xml-example/fsm/plugin.xml
similarity index 100%
rename from src/it/example/fsm/plugin.xml
rename to src/it/d2xml-example/fsm/plugin.xml
diff --git a/src/it/example/fsm/prototype.module.xml b/src/it/d2xml-example/fsm/prototype.module.xml
similarity index 100%
rename from src/it/example/fsm/prototype.module.xml
rename to src/it/d2xml-example/fsm/prototype.module.xml
diff --git a/src/it/example/pom.xml b/src/it/d2xml-example/pom.xml
similarity index 100%
rename from src/it/example/pom.xml
rename to src/it/d2xml-example/pom.xml
diff --git a/src/it/example/verify.groovy b/src/it/d2xml-example/verify.groovy
similarity index 93%
rename from src/it/example/verify.groovy
rename to src/it/d2xml-example/verify.groovy
index c631c0f..22db268 100644
--- a/src/it/example/verify.groovy
+++ b/src/it/d2xml-example/verify.groovy
@@ -1,7 +1,9 @@
+import groovy.xml.XmlSlurper
+
def moduleXmlFile = new File(basedir, 'target/extra-resources/module.xml')
-assert moduleXmlFile.exists() : "The module.xml descriptor was not created.";
+assert moduleXmlFile.exists() : "The module.xml descriptor was not created"
def doc = new XmlSlurper().parse(moduleXmlFile)
-assert doc.version == 11 : "The module.xml version was not filtered."
+assert doc.version == 11 : "The module.xml version was not filtered"
// verify commons-math3 is under -> -> and has the correct version
diff --git a/src/it/prepare-dependency-with-classifier/fsm/plugin.xml b/src/it/prepare-dependency-with-classifier/fsm/plugin.xml
new file mode 100644
index 0000000..8269993
--- /dev/null
+++ b/src/it/prepare-dependency-with-classifier/fsm/plugin.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ ${project.groupId}:${project.artifactId}:${project.version}
+
+
+ xmlresolver
+
+
+
diff --git a/src/it/prepare-dependency-with-classifier/fsm/prototype.module.xml b/src/it/prepare-dependency-with-classifier/fsm/prototype.module.xml
new file mode 100644
index 0000000..392af89
--- /dev/null
+++ b/src/it/prepare-dependency-with-classifier/fsm/prototype.module.xml
@@ -0,0 +1,16 @@
+
+
+ Monday XML Resovler
+ ${project.version}
+
+
+
+ XML Resolver
+ ${project.version}
+
+
+ xmlresolver
+
+
+
+
diff --git a/src/it/prepare-dependency-with-classifier/pom.xml b/src/it/prepare-dependency-with-classifier/pom.xml
new file mode 100644
index 0000000..b2f1d4c
--- /dev/null
+++ b/src/it/prepare-dependency-with-classifier/pom.xml
@@ -0,0 +1,82 @@
+
+
+ 4.0.0
+
+ com.monday-consulting.maven.plugins
+ dependency-with-classifier
+ 11
+ pom
+
+
+ UTF-8
+ 5.2.0
+
+
+
+
+ org.xmlresolver
+ xmlresolver
+ ${xmlresolver.version}
+
+
+ org.xmlresolver
+ xmlresolver
+ data
+ ${xmlresolver.version}
+
+
+
+
+
+
+ fsm
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.1.0
+
+
+ copy-resources
+ prepare-package
+
+ copy-resources
+
+
+ ${basedir}/target/extra-resources
+
+
+ fsm
+ true
+
+
+
+
+
+
+
+
+ com.monday-consulting.maven.plugins
+ fsm-maven-plugin
+ @project.version@
+
+ ${basedir}/target/extra-resources/plugin.xml
+ ${basedir}/target/extra-resources/prototype.module.xml
+
+
+
+ prepare-module
+ package
+
+ prepare
+
+
+
+
+
+
+
diff --git a/src/it/prepare-dependency-with-classifier/verify.groovy b/src/it/prepare-dependency-with-classifier/verify.groovy
new file mode 100644
index 0000000..80fd959
--- /dev/null
+++ b/src/it/prepare-dependency-with-classifier/verify.groovy
@@ -0,0 +1,24 @@
+import groovy.xml.XmlSlurper
+
+def fsmDir = new File(basedir, 'target/fsm-root')
+assert fsmDir.exists() : "The FSM root directory was not created"
+
+def moduleXmlFile = new File(fsmDir, 'META-INF/module.xml')
+assert moduleXmlFile.exists() : "The module.xml descriptor was not created"
+def moduleIsolatedXmlFile = new File(fsmDir, 'META-INF/module-isolated.xml')
+assert moduleIsolatedXmlFile.exists() : "The module-isolated.xml descriptor was not created"
+
+def doc = new XmlSlurper().parse(moduleXmlFile)
+assert doc.version == 11 : "The module.xml version was not filtered"
+
+// verify commons-math3 is under -> -> and has the correct version
+def resource = doc.components.'web-app'.'web-resources'.childNodes().find { it.attributes().name = "org.xmlresolver:xmlresolver" }
+assert resource != null : "org.xmlresolver:xmlresolver (no classifier) resource must exist in module.xml"
+def resourceWithClassifier = doc.components.'web-app'.'web-resources'.childNodes().find { it.attributes().name = "org.xmlresolver:xmlresolver:data" }
+assert resourceWithClassifier != null : "org.xmlresolver:xmlresolver:data (with classifier) resource must exist in module.xml"
+
+// verify dependency has been copied to /lib/
+def libDir = new File(fsmDir, 'lib');
+assert libDir.exists() : "The lib directory was not created"
+assert (new File(libDir, 'xmlresolver-5.2.0.jar').exists()) : "The resource lib 'xmlresolver-5.2.0.jar' was not copied to the lib/ directory"
+assert (new File(libDir, 'xmlresolver-5.2.0-data.jar').exists()) : "The resource lib 'xmlresolver-5.2.0.jar-data' was not copied to the lib/ directory"
diff --git a/src/it/prepare-example/fsm-assembly.xml b/src/it/prepare-example/fsm-assembly.xml
new file mode 100644
index 0000000..36a57be
--- /dev/null
+++ b/src/it/prepare-example/fsm-assembly.xml
@@ -0,0 +1,18 @@
+
+
+ fsm
+
+ zip
+
+ false
+
+
+
+ ${basedir}/target/fsm-root
+ /
+
+
+
+
diff --git a/src/it/prepare-example/fsm/plugin.xml b/src/it/prepare-example/fsm/plugin.xml
new file mode 100644
index 0000000..27fe480
--- /dev/null
+++ b/src/it/prepare-example/fsm/plugin.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ org.apache.commons:commons-math3:jar:${commons.math.version}
+
+ math
+
+
+
diff --git a/src/it/prepare-example/fsm/prototype.module.xml b/src/it/prepare-example/fsm/prototype.module.xml
new file mode 100644
index 0000000..bec796e
--- /dev/null
+++ b/src/it/prepare-example/fsm/prototype.module.xml
@@ -0,0 +1,16 @@
+
+
+ Monday Math
+ ${project.version}
+
+
+
+ Math
+ ${project.version}
+
+
+ math
+
+
+
+
diff --git a/src/it/prepare-example/pom.xml b/src/it/prepare-example/pom.xml
new file mode 100644
index 0000000..bbef8de
--- /dev/null
+++ b/src/it/prepare-example/pom.xml
@@ -0,0 +1,91 @@
+
+
+ 4.0.0
+
+ com.monday-consulting.maven.plugins
+ example
+ 11
+ pom
+
+
+ UTF-8
+ 3.6.1
+
+
+
+
+
+ fsm
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-resources-plugin
+ 3.1.0
+
+
+ copy-resources
+ prepare-package
+
+ copy-resources
+
+
+ ${basedir}/target/extra-resources
+
+
+ fsm
+ true
+
+
+
+
+
+
+
+
+ com.monday-consulting.maven.plugins
+ fsm-maven-plugin
+ @project.version@
+
+ ${basedir}/target/extra-resources/plugin.xml
+ ${basedir}/target/extra-resources/prototype.module.xml
+
+
+
+ prepare-module
+ package
+
+ prepare
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.6.0
+
+
+ fsm-assembly.xml
+
+ ${project.artifactId}-${project.version}.fsm
+ false
+ false
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
diff --git a/src/it/prepare-example/verify.groovy b/src/it/prepare-example/verify.groovy
new file mode 100644
index 0000000..5d2c740
--- /dev/null
+++ b/src/it/prepare-example/verify.groovy
@@ -0,0 +1,24 @@
+import groovy.xml.XmlSlurper
+
+def fsmDir = new File(basedir, 'target/fsm-root')
+assert fsmDir.exists() : "The FSM root directory was not created"
+
+def moduleXmlFile = new File(fsmDir, 'META-INF/module.xml')
+assert moduleXmlFile.exists() : "The module.xml descriptor was not created"
+def moduleIsolatedXmlFile = new File(fsmDir, 'META-INF/module-isolated.xml')
+assert moduleIsolatedXmlFile.exists() : "The module-isolated.xml descriptor was not created"
+
+def doc = new XmlSlurper().parse(moduleXmlFile)
+assert doc.version == 11 : "The module.xml version was not filtered"
+
+// verify commons-math3 is under -> -> and has the correct version
+def resource = doc.components.'web-app'.'web-resources'.childNodes().find { it.attributes().name = "org.apache.commons:commons-math3" }
+assert resource != null : "commons-math3 resource must exist in module.xml"
+def resourceVersion = resource.attributes().version
+assert resourceVersion == "3.6.1" : "commons-math3 version must be 3.6.1"
+
+// verify dependency has been copied to /lib/
+def libDir = new File(fsmDir, 'lib');
+assert libDir.exists() : "The lib directory was not created"
+def resourceLib = new File(libDir, 'commons-math3-3.6.1.jar')
+assert resourceLib.exists() : "The resource lib 'commons-math3-3.6.1.jar' was not copied to the lib/ directory"
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/AttachFSMMojo.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/AttachFSMMojo.java
index 4f3d6c7..db9f91b 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/AttachFSMMojo.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/AttachFSMMojo.java
@@ -16,12 +16,8 @@
limitations under the License.
*/
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugins.annotations.*;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.MavenProjectHelper;
-
-import java.io.File;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
/**
* This Mojo attaches the assembled FSM as a project artifact.
@@ -29,36 +25,13 @@
* @author Oliver Degener
* @since 1.6.0
*/
+@SuppressWarnings("unused")
@Mojo(name = "attachFSM", defaultPhase = LifecyclePhase.PACKAGE)
-class AttachFSMMojo extends AbstractMojo {
-
- @Component
- private MavenProjectHelper projectHelper;
-
- /**
- * The filename of the assembled distribution file.
- */
- @Parameter(property = "fsmFile", defaultValue = "${project.artifactId}-${project.version}.fsm.zip")
- private String fsmFile;
-
- /**
- * The artifact type, defaults to fsm.
- */
- @Parameter(property = "type", defaultValue = "fsm")
- private String type;
-
- @Parameter(defaultValue = "${project}", readonly = true, required = true)
- private MavenProject project;
+class AttachFSMMojo extends BaseFSMMojo {
@Override
public void execute() {
- final String targetDir = project.getBuild().getDirectory();
-
- String path = targetDir.concat(File.separator).concat(fsmFile);
- File file = new File(path);
-
- getLog().info("Attaching '" + type + "' artifact: " + file.getAbsolutePath());
- projectHelper.attachArtifact(project, type, null, file);
+ attachFSM();
}
}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/BaseDependencyModuleMojo.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/BaseDependencyModuleMojo.java
new file mode 100644
index 0000000..ef11dea
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/BaseDependencyModuleMojo.java
@@ -0,0 +1,128 @@
+package com.monday_consulting.maven.plugins.fsm;
+
+import com.monday_consulting.maven.plugins.fsm.jaxb.FsmMavenPluginType;
+import com.monday_consulting.maven.plugins.fsm.jaxb.ModuleType;
+import com.monday_consulting.maven.plugins.fsm.maven.MavenCoordinate;
+import com.monday_consulting.maven.plugins.fsm.util.Module;
+import com.monday_consulting.maven.plugins.fsm.util.ModuleIdParser;
+import com.monday_consulting.maven.plugins.fsm.util.resolver.IResolver;
+import com.monday_consulting.maven.plugins.fsm.util.resolver.MavenGetArtifactsResolver;
+import com.monday_consulting.maven.plugins.fsm.xml.FsmPluginConfigParser;
+import com.monday_consulting.maven.plugins.fsm.xml.PrototypeXml;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+abstract class BaseDependencyModuleMojo extends BaseFSMMojo {
+
+ /**
+ * The xml containing the configuration for the plugin.
+ */
+ @SuppressWarnings("unused")
+ @Parameter(defaultValue = "${configXml}")
+ private File configXml;
+
+ /**
+ * The xml with the prototype for the target-xml.
+ */
+ @SuppressWarnings("unused")
+ @Parameter(defaultValue = "${prototypeXml}")
+ private File prototypeXml;
+
+ /**
+ * The Maven Session.
+ */
+ @SuppressWarnings("unused")
+ @Parameter(defaultValue = "${session}", readonly = true, required = true)
+ private MavenSession session;
+
+ /**
+ * The projects in the reactor.
+ */
+ @Parameter(defaultValue = "${reactorProjects}", readonly = true)
+ protected List reactorProjects;
+
+ /**
+ * The entry point towards a Maven version independent way of resolving
+ * artifacts (handles both Maven 3.0 Sonatype and Maven 3.1+ eclipse Aether
+ * implementations).
+ */
+ @SuppressWarnings("unused")
+ @Component
+ private ArtifactResolver artifactResolver;
+
+ @Component
+ @SuppressWarnings("unused")
+ private ProjectBuilder projectBuilder;
+
+ /**
+ * Log Projects and their resolved dependencies via MavenProject.getArtifacts().
+ *
+ * @param reactorProjects MavenProjects in the current reactor
+ */
+ protected void checkReactor(final List reactorProjects) {
+ for (final MavenProject reactorProject : reactorProjects) {
+ final String msg = "Check resolved Artifacts for: " +
+ "\ngroudId: " + reactorProject.getGroupId() +
+ "\nartifactId: " + reactorProject.getArtifactId() +
+ "\nversion: " + reactorProject.getVersion();
+
+ getLog().debug(msg);
+
+ if (reactorProject.getArtifacts() == null || reactorProject.getArtifacts().isEmpty()) {
+ getLog().debug("+ Dependencies not resolved or reactor project has no dependencies!");
+ } else {
+ for (final Artifact artifact : reactorProject.getArtifacts()) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(" + " + artifact.toString());
+ }
+ }
+ }
+ }
+ }
+
+ protected Map resolveModulesWithDependencies() throws MojoExecutionException, MojoFailureException {
+ final FsmMavenPluginType config = parseConfig();
+ final IResolver resolver = new MavenGetArtifactsResolver(getLog(), session, artifactResolver, reactorProjects, projectBuilder, project);
+ final Map modules = new HashMap<>();
+ for (final ModuleType moduleType : config.getModules().getModule()) {
+ if (modules.containsKey(moduleType.getDependencyTagValueInXml())) {
+ throw new MojoFailureException("Properties for Module: " + moduleType.getDependencyTagValueInXml() +
+ "defined twice\tFix to prevent unpredictable behaviour!\tPlease contact Responsible Developer, XSD has to be fixed!");
+ }
+
+ getLog().debug("Resolving module for dependency tag " + moduleType.getDependencyTagValueInXml());
+
+ List artifacts = ModuleIdParser.parseModuleTypeIds(moduleType);
+ List mavenProjects = resolver.resolveMavenProjects(artifacts);
+
+ Module module = new Module(getLog(), moduleType, mavenProjects, config.getScopes().getScope());
+
+ modules.put(moduleType.getDependencyTagValueInXml(), module);
+ }
+ return modules;
+ }
+
+ protected FsmMavenPluginType parseConfig() throws MojoExecutionException {
+ getLog().debug("Create config-xml-Object");
+ FsmPluginConfigParser fsmPluginConfigParser = new FsmPluginConfigParser(getLog());
+ return fsmPluginConfigParser.bindXmlConfigToPojo(configXml);
+ }
+
+ protected PrototypeXml createPrototype() {
+ getLog().debug("Creating PrototypeXml-Object");
+ return new PrototypeXml(getLog(), prototypeXml);
+ }
+
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/BaseFSMMojo.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/BaseFSMMojo.java
new file mode 100644
index 0000000..206601f
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/BaseFSMMojo.java
@@ -0,0 +1,41 @@
+package com.monday_consulting.maven.plugins.fsm;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+
+import java.io.File;
+import java.nio.file.Path;
+
+abstract class BaseFSMMojo extends AbstractMojo {
+
+ @SuppressWarnings("unused")
+ @Parameter(defaultValue = "${project}", readonly = true, required = true)
+ protected MavenProject project;
+
+ /**
+ * The filename of the assembled distribution file.
+ */
+ @SuppressWarnings("unused")
+ @Parameter(property = "fsmFile", defaultValue = "${project.artifactId}-${project.version}.fsm.zip")
+ private String fsmFile;
+
+ /**
+ * The artifact type, defaults to fsm.
+ */
+ @SuppressWarnings("unused")
+ @Parameter(property = "type", defaultValue = "fsm")
+ private String type;
+
+ @SuppressWarnings("unused")
+ @Component
+ private MavenProjectHelper projectHelper;
+
+ void attachFSM() {
+ final File file = Path.of(project.getBuild().getDirectory()).resolve(fsmFile).toFile();
+ getLog().info("Attaching '" + type + "' artifact: " + file.getAbsolutePath());
+ projectHelper.attachArtifact(project, type, null, file);
+ }
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojo.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojo.java
index 4dd442a..964247c 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojo.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojo.java
@@ -16,44 +16,15 @@
limitations under the License.
*/
-import com.monday_consulting.maven.plugins.fsm.jaxb.FsmMavenPluginType;
-import com.monday_consulting.maven.plugins.fsm.jaxb.ModuleType;
-import com.monday_consulting.maven.plugins.fsm.jaxb.ScopesType;
import com.monday_consulting.maven.plugins.fsm.util.Module;
-import com.monday_consulting.maven.plugins.fsm.util.PrototypeXml;
-import com.monday_consulting.maven.plugins.fsm.util.XmlValidationEventHandler;
-import com.monday_consulting.maven.plugins.fsm.util.resolver.IResolver;
-import com.monday_consulting.maven.plugins.fsm.util.resolver.MavenGetArtifactsResolver;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.AbstractMojo;
+import com.monday_consulting.maven.plugins.fsm.xml.PrototypeXml;
+import com.monday_consulting.maven.plugins.fsm.xml.ModuleXmlWriter;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.*;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectBuilder;
-import org.codehaus.plexus.util.WriterFactory;
-import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
-import org.codehaus.plexus.util.xml.XmlStreamWriter;
-import org.codehaus.plexus.util.xml.Xpp3Dom;
-import org.codehaus.plexus.util.xml.Xpp3DomWriter;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
-import org.xml.sax.SAXException;
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.transform.stream.StreamSource;
-import javax.xml.validation.Schema;
-import javax.xml.validation.SchemaFactory;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/**
@@ -74,50 +45,12 @@
* @author Kassim Hölting
* @since 1.0.0
*/
+@SuppressWarnings("unused")
@Mojo(name = "dependencyToXML",
defaultPhase = LifecyclePhase.PACKAGE,
aggregator = true,
requiresDependencyResolution = ResolutionScope.COMPILE)
-class DependencyToXMLMojo extends AbstractMojo {
-
- /**
- * The entry point to Aether, i.e. the component doing all the work.
- */
- @Component
- private RepositorySystem repoSystem;
-
- @Component
- private ProjectBuilder projectBuilder;
-
- /**
- * The current repository/network configuration of Maven.
- */
- @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
- private RepositorySystemSession repoSession;
-
- /**
- * The Maven-Project
- */
- @Parameter(defaultValue = "${project}", readonly = true)
- private MavenProject mavenProject;
-
- /**
- * The projects in the reactor.
- */
- @Parameter(defaultValue = "${reactorProjects}", readonly = true)
- private List reactorProjects;
-
- /**
- * The xml containing the configuration for the plugin.
- */
- @Parameter(defaultValue = "${configXml}")
- private File configXml;
-
- /**
- * The xml with the prototype for the target-xml.
- */
- @Parameter(defaultValue = "${prototypeXml}")
- private File prototypeXml;
+class DependencyToXMLMojo extends BaseDependencyModuleMojo {
/**
* The xml the module data write to.
@@ -128,139 +61,23 @@ class DependencyToXMLMojo extends AbstractMojo {
/**
* {@inheritDoc}
*/
+ @Override
public void execute() throws MojoExecutionException, MojoFailureException {
try {
getLog().debug("*** Starting DependencyToXMLMojo");
checkReactor(reactorProjects);
- getLog().debug("Create config-xml-Object");
-
- final FsmMavenPluginType config = bindXmlConfigToPojo(configXml);
-
- getLog().debug("Creating PrototypeXml-Object");
-
- PrototypeXml prototype = new PrototypeXml(getLog(), prototypeXml);
-
- if (getLog().isDebugEnabled()) {
- getLog().debug("Getting target-file: " + targetXml.getAbsoluteFile());
- getLog().debug("Enhance created Modules");
- }
-
- final IResolver resolver = new MavenGetArtifactsResolver(getLog(), reactorProjects, repoSystem, repoSession, projectBuilder, mavenProject);
- final Map modules = new HashMap<>();
- for (final ModuleType moduleType : config.getModules().getModule()) {
- if (modules.containsKey(moduleType.getDependencyTagValueInXml())) {
- throw new MojoFailureException("Properties for Module: " + moduleType.getDependencyTagValueInXml() +
- "defined twice\tFix to prevent unpredictable behaviour!\tPlease contact Responsible Developer, XSD has to be fixed!");
- }
- modules.put(moduleType.getDependencyTagValueInXml(), resolver.resolve(moduleType, config.getScopes().getScope()));
- }
-
- getLog().debug("Enhance Prototype for TargetXml");
-
+ final PrototypeXml prototype = createPrototype();
+ final Map modules = resolveModulesWithDependencies();
prototype.fillPrototypeDom(modules);
- getLog().debug("Write TargetXml-File");
-
- writeDomToTarget(targetXml, prototype.getPrototypeDom());
-
- getLog().debug("Dependencies written to Module-XML:\n\t" + prototype.getPrototypeDom().toString());
+ ModuleXmlWriter moduleXmlWriter = new ModuleXmlWriter(getLog());
+ moduleXmlWriter.writeDomToTarget(targetXml, prototype.getPrototypeDom());
getLog().debug("*** DependencyToXMLMojo finished");
- } catch (XmlPullParserException | IOException e) {
+ } catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
- /**
- * Log Projects and their resolved dependencies via MavenProject.getArtifacts().
- *
- * @param reactorProjects MavenProjects in the current reactor
- */
- private void checkReactor(final List reactorProjects) {
- for (final MavenProject reactorProject : reactorProjects) {
- final String msg = "Check resolved Artifacts for: " +
- "\ngroudId: " + reactorProject.getGroupId() +
- "\nartifactId: " + reactorProject.getArtifactId() +
- "\nversion: " + reactorProject.getVersion();
-
- getLog().debug(msg);
-
- if (reactorProject.getArtifacts() == null || reactorProject.getArtifacts().isEmpty()) {
- getLog().debug("+ Dependencies not resolved or reactor project has no dependencies!");
- } else {
- for (final Artifact artifact : reactorProject.getArtifacts()) {
- if (getLog().isDebugEnabled()) {
- getLog().debug(" + " + artifact.toString());
- }
- }
- }
- }
- }
-
- /**
- * Validate a config-XML against the Plugin-XSD.
- * Bind config-XML to generated POJOs.
- *
- * @param configXml The config-file to use
- * @return WebformsMavenPluginType The corresponding Java-Object of the plugin-configuration.
- * @throws MojoExecutionException in case of marshalling exception for the fsm-plugin.xsd.
- */
- private FsmMavenPluginType bindXmlConfigToPojo(final File configXml) throws MojoExecutionException {
- getLog().debug("*** Constructing ConfigXml-Object");
-
- try {
- final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
- final Schema schema = sf.newSchema(getClass().getResource("/fsm-plugin.xsd"));
- final StreamSource streamSource = new StreamSource(configXml);
- final JAXBContext jaxbContext = JAXBContext.newInstance(FsmMavenPluginType.class);
- final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
- unmarshaller.setSchema(schema);
- unmarshaller.setEventHandler(new XmlValidationEventHandler(getLog()));
-
- final JAXBElement jaxbElement = unmarshaller.unmarshal(streamSource, FsmMavenPluginType.class);
- FsmMavenPluginType config = jaxbElement.getValue();
- applyDefaultConfiguration(config);
- return config;
- } catch (SAXException e) {
- throw new MojoExecutionException(e, "Error while parsing file with SAX", e.getMessage());
- } catch (JAXBException e) {
- throw new MojoExecutionException(e, "Error while binding xml-file with JAXB", e.getMessage());
- }
- }
-
- void applyDefaultConfiguration(FsmMavenPluginType config) {
- if (config.getScopes() == null) {
- ScopesType defaultScopesType = new ScopesType();
- List defaultScopes = defaultScopesType.getScope();
- defaultScopes.add("runtime");
- defaultScopes.add("compile");
- config.setScopes(defaultScopesType);
- }
-
- for (ModuleType moduleType : config.getModules().getModule()) {
- if (moduleType.getPrefix() == null) {
- moduleType.setPrefix("");
- }
- }
- }
-
- /**
- * Write a DOM-Tree to a target file.
- *
- * @param target File to write to.
- * @param dom dom to write to file.
- * @throws IOException in case of unexpected writer exceptions.
- */
- private void writeDomToTarget(final File target, final Xpp3Dom dom) throws IOException {
- getLog().info("Writing module descriptor: " + target.getAbsolutePath());
-
- // ensure that the target directory exists
- Files.createDirectories(target.toPath().getParent());
-
- final XmlStreamWriter writer = WriterFactory.newXmlWriter(target);
- final PrettyPrintXMLWriter pretty = new PrettyPrintXMLWriter(writer);
- Xpp3DomWriter.write(pretty, dom);
- writer.close();
- }
}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/PrepareMojo.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/PrepareMojo.java
new file mode 100644
index 0000000..a717138
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/PrepareMojo.java
@@ -0,0 +1,73 @@
+package com.monday_consulting.maven.plugins.fsm;
+
+import com.monday_consulting.maven.plugins.fsm.assembly.DependencyAssembler;
+import com.monday_consulting.maven.plugins.fsm.util.Module;
+import com.monday_consulting.maven.plugins.fsm.xml.ModuleXmlWriter;
+import com.monday_consulting.maven.plugins.fsm.xml.PrototypeXml;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+
+@SuppressWarnings("unused")
+@Mojo(name = "prepare",
+ defaultPhase = LifecyclePhase.PACKAGE,
+ aggregator = true,
+ requiresDependencyResolution = ResolutionScope.COMPILE)
+class PrepareMojo extends BaseDependencyModuleMojo {
+
+ /**
+ * Flag to control whether the FSM file should be attached as a project artifact.
+ */
+ @Parameter(property = "attach", defaultValue = "true", required = true)
+ private boolean attach;
+
+ /**
+ * The xml the module data write to.
+ */
+ @Parameter(name = "fsm-root", defaultValue = "fsm-root")
+ private String fsmRoot;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ try {
+ getLog().debug("*** Starting PrepareMojo");
+ checkReactor(reactorProjects);
+
+ final PrototypeXml prototype = createPrototype();
+
+ final Map modules = resolveModulesWithDependencies();
+
+ getLog().debug("Enhance Prototype for TargetXml");
+
+ prototype.fillPrototypeDom(modules);
+
+ Path fsmRootPath = Path.of(project.getBuild().getDirectory(), fsmRoot);
+ getLog().debug("FSM Root Directory is " + fsmRootPath);
+ Files.createDirectories(fsmRootPath);
+
+ ModuleXmlWriter moduleXmlWriter = new ModuleXmlWriter(getLog());
+ moduleXmlWriter.writeDomToTarget(fsmRootPath, prototype.getPrototypeDom());
+
+ getLog().debug("Copying dependencies to " + fsmRootPath);
+ new DependencyAssembler(getLog()).copyDependenciesForModuleAssembly(fsmRootPath, modules.values());
+ getLog().debug("Module dependencies were successfully copied.");
+
+ if (attach) {
+ attachFSM();
+ }
+
+ getLog().debug("*** PrepareMojo finished");
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/assembly/DependencyAssembler.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/assembly/DependencyAssembler.java
new file mode 100644
index 0000000..90c49d1
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/assembly/DependencyAssembler.java
@@ -0,0 +1,45 @@
+package com.monday_consulting.maven.plugins.fsm.assembly;
+
+import com.monday_consulting.maven.plugins.fsm.util.Module;
+import org.apache.maven.plugin.logging.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Collection;
+import java.util.List;
+
+public class DependencyAssembler {
+
+ private final Log log;
+
+ public DependencyAssembler(Log log) {
+ this.log = log;
+ }
+
+ public void copyDependenciesForModuleAssembly(Path fsmRoot, Collection modules) throws IOException {
+ final Path libDir = fsmRoot.resolve(Module.LIB_PATH);
+ Files.createDirectories(libDir);
+
+ modules.stream()
+ .map(Module::getDependencies).flatMap(List::stream)
+ .filter(artifact -> {
+ File artifactFile = artifact.getFile();
+ if (artifactFile == null) {
+ log.warn("A dependency cannot be resolved and will be missing in the FSM: " + artifact);
+ return false;
+ }
+ return true;
+ })
+ .forEach(artifact -> {
+ Path targetPath = libDir.resolve(artifact.getFile().getName());
+ try {
+ Files.copy(artifact.getFile().toPath(), targetPath, StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to copy artifact to FSM directory.", e);
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/maven/MavenCoordinate.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/maven/MavenCoordinate.java
new file mode 100644
index 0000000..3c9f250
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/maven/MavenCoordinate.java
@@ -0,0 +1,68 @@
+package com.monday_consulting.maven.plugins.fsm.maven;
+
+public class MavenCoordinate {
+
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ private String extension;
+
+ private String classifier;
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getExtension() {
+ return extension;
+ }
+
+ public void setExtension(String extension) {
+ this.extension = extension;
+ }
+
+ public String getClassifier() {
+ return classifier;
+ }
+
+ public void setClassifier(String classifier) {
+ this.classifier = classifier;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder().append(groupId).append(':')
+ .append(artifactId).append(':').append(getExtension());
+
+ if (classifier != null) {
+ sb.append(':').append(classifier);
+ }
+
+ sb.append(':').append(version);
+
+ return sb.toString();
+ }
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ConflictResolver.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ConflictResolver.java
index 919667f..305a808 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ConflictResolver.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ConflictResolver.java
@@ -31,6 +31,8 @@ public List resolveVersionConflicts(List artifacts) {
// first occurrence wins
log.info("Resolving conflict for " + conflictId + " with first seen version " + artifact.getVersion());
resolvedConflicts.put(conflictId, artifact);
+ } else {
+ log.debug("Alternative version for " + conflictId + " is " + artifact.getVersion());
}
}
});
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/Module.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/Module.java
index 3222b1e..d5245ab 100755
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/Module.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/Module.java
@@ -20,13 +20,11 @@
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.xml.Xpp3Dom;
-import org.eclipse.aether.artifact.DefaultArtifact;
import java.io.File;
import java.io.IOException;
@@ -46,86 +44,71 @@ public class Module {
private static final String RESOURCE_TAG = "resource";
private static final String ROOT_TAG = "root";
+ /**
+ * The lib path for JARs in the FSM.
+ */
+ public static final String LIB_PATH = "lib/";
+
private final Log log;
private final ModuleType moduleType;
- private final String prefix;
private final List dependencyScopes;
private final String dependencyTagValueInXml;
private final Resource resource;
- private final List artifacts = new ArrayList<>();
-
- private List projects;
+ private final List dependencies;
private final Map includesMap;
private final Map excludesMap;
+ private final List projects;
/**
* @param log The logger.
* @param moduleType The module component configuration.
* @param scopes The dependency scopes that will be included (like compile, runtime).
- * @throws MojoExecutionException in case of a general failures.
*/
- public Module(final Log log, final ModuleType moduleType, final List scopes) throws MojoExecutionException,
- MojoFailureException {
+ public Module(final Log log, final ModuleType moduleType, final List mavenProjects,
+ final List scopes) throws MojoFailureException {
this.log = log;
this.moduleType = moduleType;
- if (moduleType.getId() == null && moduleType.getIds() == null) {
- throw new MojoExecutionException("Module construction failed: Missing module property ''.");
- }
-
- if (moduleType.getId() != null) {
- artifacts.add(parseID(moduleType.getId()));
- }
-
- if (moduleType.getIds() != null) {
- for (String id : moduleType.getIds().getId()) {
- artifacts.add(parseID(id));
- }
- }
-
- prefix = this.moduleType.getPrefix();
dependencyScopes = scopes;
dependencyTagValueInXml = this.moduleType.getDependencyTagValueInXml();
resource = this.moduleType.getResource();
includesMap = getIncludesMap();
excludesMap = getExcludesMap(includesMap);
- }
-
- private static DefaultArtifact parseID(String str) throws MojoExecutionException {
- final String[] coords = str.split(":");
- if (coords.length < 3) {
- throw new MojoExecutionException("Incomplete artifact ID specified: " + str);
+ if (moduleType.getPrefix() != null) {
+ if (LIB_PATH.equals(moduleType.getPrefix())) {
+ log.info("The module prefix 'lib/' equals the default convention and" +
+ " should be removed as the parameter is no longer considered.");
+ } else {
+ log.warn("The element in the module descriptor has been removed and has no effect." +
+ " All dependencies will be placed under '/lib' by convention.");
+ }
}
- return new DefaultArtifact(coords[0], coords[1],
- coords.length > 4 ? coords[4] : null, coords[2], coords.length > 3 ? coords[3] : null);
+ this.projects = mavenProjects;
+
+ this.dependencies = resolveDependencies(mavenProjects);
+ }
+
+ public List getDependencies() {
+ return dependencies;
}
private Xpp3Dom getWebResourceTmpDom(final String name, final String dirPath) {
final Xpp3Dom dom = new Xpp3Dom(RESOURCE_TAG);
// fix windows paths to work with FirstSpirit module loader
dom.setAttribute("target", "/" + dirPath.replace("\\", "/"));
- final String value = getResource().getPrefix() != null ? getResource().getPrefix() + name : name;
+ final String value = resource.getPrefix() != null ? resource.getPrefix() + name : name;
dom.setValue(value.replace("\\", "/"));
return dom;
}
- /**
- * Creates an XML dom for the resolved module artifacts.
- *
- * @throws MojoFailureException in case of plugin configuration problems.
- */
- public Xpp3Dom getModuleDependencyDom() throws MojoFailureException {
- log.info("Processing dependency tag '" + dependencyTagValueInXml + "'");
- final Xpp3Dom dom = new Xpp3Dom(ROOT_TAG);
- final HashSet history = new HashSet<>();
-
+ protected List resolveDependencies(List projects) {
final Set resolvedModuleArtifacts = new LinkedHashSet<>();
- for (final MavenProject mavenProject : getProjects()) {
+ for (final MavenProject mavenProject : projects) {
log.info("Resolving dependencies for module " + mavenProject.getGroupId()
+ ":" + mavenProject.getArtifactId());
@@ -136,28 +119,45 @@ public Xpp3Dom getModuleDependencyDom() throws MojoFailureException {
if (artifactType.equals("jar") || artifactType.equals("bundle")) {
log.debug("Adding the project artifact itself: " + projectArtifact.getArtifactId() +
- ", with absolute file: " + projectArtifact.getFile().getAbsoluteFile() + "; finalname: " +
- mavenProject.getBuild().getFinalName());
+ ", with file: " + projectArtifact.getFile() + "; finalname: " +
+ mavenProject.getBuild().getFinalName());
resolvedModuleArtifacts.add(projectArtifact);
}
-
- if (artifactType.equals("war") || artifactType.equals("zip")) {
- addArchiveFileIncludesToDom(dom, mavenProject, history);
- }
}
List filteredModuleArtifacts = getFilteredModuleArtifacts(resolvedModuleArtifacts);
ConflictResolver conflictResolver = new ConflictResolver(log, dependencyTagValueInXml);
- List moduleArtifacts = conflictResolver.resolveVersionConflicts(filteredModuleArtifacts);
+ return conflictResolver.resolveVersionConflicts(filteredModuleArtifacts);
+ }
- if (moduleArtifacts.isEmpty()) {
+ /**
+ * Creates an XML dom for the resolved module artifacts.
+ *
+ * @throws MojoFailureException in case of plugin configuration problems.
+ */
+ public Xpp3Dom getModuleDependencyDom() throws MojoFailureException {
+ log.info("Processing dependency tag '" + dependencyTagValueInXml + "'");
+ final Xpp3Dom dom = new Xpp3Dom(ROOT_TAG);
+ final HashSet history = new HashSet<>();
+
+ for (MavenProject project : projects) {
+
+ final Artifact projectArtifact = project.getArtifact();
+ final String artifactType = projectArtifact.getType();
+
+ if (artifactType.equals("war") || artifactType.equals("zip")) {
+ addArchiveFileIncludesToDom(dom, project, history);
+ }
+ }
+
+ if (dependencies.isEmpty()) {
log.warn("No artifacts found for dependency tag '" + dependencyTagValueInXml + "'. This is" +
" most likely an error in the build configuration. Please make sure that all reactor projects" +
" have been processed before running the FSM plugin and have not been modified after packaging.");
}
- addArtifactsToDom(dom, moduleArtifacts, history);
+ addArtifactsToDom(dom, dependencies, history);
addIncludesToDom(dom, history);
sortChildren(dom);
return dom;
@@ -193,7 +193,19 @@ private void sortChildren(Xpp3Dom src) {
private void addArtifactsToDom(Xpp3Dom dom, List filteredModuleArtifacts, HashSet history) {
for (final Artifact artifact : filteredModuleArtifacts) {
- String value = getPrefix() + artifact.getFile().getName();
+ final File artifactFile = artifact.getFile();
+
+ if (artifactFile == null) {
+ final String unresolvedArtifact = String.format("%s:%s:%s:%s", artifact.getGroupId(),
+ artifact.getArtifactId(), artifact.getType(), artifact.getVersion());
+ final String errorMsg = "The required artifact " + unresolvedArtifact + " could not be" +
+ " resolved. Please ensure that all modules have been build or execute the plugin from the" +
+ " project root.";
+ log.error(errorMsg);
+ throw new RuntimeException(errorMsg);
+ }
+
+ String value = LIB_PATH + artifactFile.getName();
if (!history.contains(value)) {
history.add(value);
@@ -206,7 +218,8 @@ private void addArtifactsToDom(Xpp3Dom dom, List filteredModuleArtifac
if (moduleType.getFirstSpiritMode() != null && !moduleType.getFirstSpiritMode().isEmpty()) {
tmpDom.setAttribute("mode", moduleType.getFirstSpiritMode().trim());
}
- tmpDom.setAttribute("name", artifact.getGroupId() + ":" + artifact.getArtifactId());
+
+ tmpDom.setAttribute("name", formatArtifactName(artifact));
tmpDom.setAttribute("version", artifact.getBaseVersion());
tmpDom.setValue(value);
@@ -215,6 +228,23 @@ private void addArtifactsToDom(Xpp3Dom dom, List filteredModuleArtifac
}
}
+ /**
+ * Constructs a formatted string representing the artifact details.
+ * Format: groupId:artifactId[:classifier] (classifier included if present).
+ *
+ * @param artifact Artifact object to be formatted.
+ * @return Formatted artifact details as a string.
+ */
+ private static String formatArtifactName(Artifact artifact) {
+ String formattedName = artifact.getGroupId() + ":" + artifact.getArtifactId();
+
+ if (artifact.hasClassifier()) {
+ formattedName += ":" + artifact.getClassifier();
+ }
+
+ return formattedName;
+ }
+
private void addArchiveFileIncludesToDom(final Xpp3Dom dom, final MavenProject mavenProject, HashSet history)
throws MojoFailureException {
try {
@@ -224,15 +254,13 @@ private void addArchiveFileIncludesToDom(final Xpp3Dom dom, final MavenProject m
File targetDir = extractArtifactToTargetDir(mavenProject);
- final Resource res = getResource();
+ final Resource res = resource;
if (res == null || res.getIncludes() == null || res.getIncludes().getInclude().isEmpty()) {
// if there are no resources or includes then there are no files to handle
return;
}
- if (res.getPrefix() == null || res.getPrefix().isEmpty()) {
- log.warn("No defined. Prefix would be set to root.");
- }
+
if (res.getWebXml() == null || res.getWebXml().isEmpty()) {
throw new MojoFailureException("Module " + mavenProject.getArtifactId() + " from archive type " +
mavenProject.getArtifact().getType() + " detected. No defined.");
@@ -289,7 +317,7 @@ private void addIncludesToDom(Xpp3Dom dom, HashSet history) {
tmpDom.setAttribute("mode", moduleType.getFirstSpiritMode().trim());
}
- tmpDom.setValue(getPrefix() + includeType.getFileName());
+ tmpDom.setValue(LIB_PATH + includeType.getFileName());
dom.addChild(tmpDom);
}
}
@@ -358,14 +386,25 @@ private File extractArtifactToTargetDir(MavenProject mavenProject) throws IOExce
File baseDir = new File(mavenProject.getBasedir() + targetFileDir);
if (!baseDir.exists()) {
- final File artifactFile = mavenProject.getArtifact().getFile();
+ Artifact artifact = mavenProject.getArtifact();
+ if (artifact == null || artifact.getFile() == null) {
+ final String unresolvedArtifact = String.format("%s:%s:%s:%s", mavenProject.getGroupId(),
+ mavenProject.getArtifactId(), mavenProject.getPackaging(), mavenProject.getVersion());
+ final String errorMsg = "The required artifact " + unresolvedArtifact + " could not be" +
+ " resolved. Please ensure that all modules have been build or execute the plugin from the" +
+ " project root.";
+ log.error(errorMsg);
+ throw new RuntimeException(errorMsg);
+ }
+
+ final File artifactFile = artifact.getFile();
try (final ZipFile fileToExtract = new ZipFile(artifactFile)) {
if (!fileToExtract.isValidZipFile()) {
- throw new ZipException("No valid ZIP file: " + mavenProject.getArtifact().getFile());
+ throw new ZipException("No valid ZIP file: " + artifact.getFile());
}
if (fileToExtract.isEncrypted()) {
- throw new ZipException("The ZIP file is password encrypted: " + mavenProject.getArtifact().getFile());
+ throw new ZipException("The ZIP file is password encrypted: " + artifact.getFile());
}
baseDir = new File(mavenProject.getParent().getBasedir().getAbsolutePath() + targetFileDir);
@@ -376,31 +415,4 @@ private File extractArtifactToTargetDir(MavenProject mavenProject) throws IOExce
return baseDir;
}
- private String getPrefix() {
- return prefix;
- }
-
- public String getDependencyTagValueInXml() {
- return dependencyTagValueInXml;
- }
-
- private Resource getResource() {
- return resource;
- }
-
- private List getProjects() {
- return projects;
- }
-
- public void setProjects(List projects) {
- this.projects = projects;
- }
-
- public List getDependencyScopes() {
- return dependencyScopes;
- }
-
- public List getArtifacts() {
- return artifacts;
- }
}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ModuleIdParser.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ModuleIdParser.java
new file mode 100644
index 0000000..2ce7375
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/ModuleIdParser.java
@@ -0,0 +1,54 @@
+package com.monday_consulting.maven.plugins.fsm.util;
+
+import com.monday_consulting.maven.plugins.fsm.jaxb.ModuleType;
+import com.monday_consulting.maven.plugins.fsm.maven.MavenCoordinate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ModuleIdParser {
+
+ public static List parseModuleTypeIds(ModuleType moduleType) {
+
+ final List artifacts = new ArrayList<>();
+
+ if (moduleType.getId() == null && moduleType.getIds() == null) {
+ throw new RuntimeException("ModuleType parsing failed: Missing module property '' or ''.");
+ }
+
+ if (moduleType.getId() != null) {
+ artifacts.add(parseID(moduleType.getId()));
+ }
+
+ if (moduleType.getIds() != null) {
+ for (String id : moduleType.getIds().getId()) {
+ artifacts.add(parseID(id));
+ }
+ }
+
+ return artifacts;
+ }
+
+ private static MavenCoordinate parseID(String str) throws RuntimeException {
+ final String[] coords = str.split(":");
+
+ if (coords.length < 3) {
+ throw new RuntimeException("Incomplete artifact ID specified: " + str);
+ }
+
+ final String groupId = coords[0];
+ final String artifactId = coords[1];
+ final String extension = coords[2];
+ final String version = coords.length > 3 ? coords[3] : null;
+ final String classifier = coords.length > 4 ? coords[4] : null;
+
+ MavenCoordinate coordinate = new MavenCoordinate();
+ coordinate.setGroupId(groupId);
+ coordinate.setArtifactId(artifactId);
+ coordinate.setVersion(version);
+ coordinate.setClassifier(classifier);
+ coordinate.setExtension(extension);
+ return coordinate;
+ }
+
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/IResolver.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/IResolver.java
index b6d3a4c..5280540 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/IResolver.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/IResolver.java
@@ -16,10 +16,8 @@
limitations under the License.
*/
-import com.monday_consulting.maven.plugins.fsm.jaxb.ModuleType;
-import com.monday_consulting.maven.plugins.fsm.util.Module;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
+import com.monday_consulting.maven.plugins.fsm.maven.MavenCoordinate;
+import org.apache.maven.project.MavenProject;
import java.util.List;
@@ -30,14 +28,14 @@
* @since 1.0.0
*/
public interface IResolver {
+
/**
- * Resolve the dependencies for a maven artifact.
+ * Resolve a MavenProject for every artifact.
+ * The MavenProject may be part of the reactor, part of the local workspace or a virtual project from a repository.
*
- * @param moduleType The module component configuration.
- * @param scopes The dependency scopes that will be included.
+ * @param artifacts This list of artifacts represented as a coordinate
* @return The module component.
- * @throws MojoFailureException in case if no dependency for the configured module type could be found or could not be resolved.
- * @throws MojoExecutionException in case of a general failures.
*/
- Module resolve(ModuleType moduleType, List scopes) throws MojoFailureException, MojoExecutionException;
+ List resolveMavenProjects(List artifacts);
+
}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/MavenGetArtifactsResolver.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/MavenGetArtifactsResolver.java
index e3a108f..7c9e674 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/MavenGetArtifactsResolver.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/util/resolver/MavenGetArtifactsResolver.java
@@ -16,24 +16,23 @@
limitations under the License.
*/
-import com.monday_consulting.maven.plugins.fsm.jaxb.ModuleType;
-import com.monday_consulting.maven.plugins.fsm.util.Module;
+import com.monday_consulting.maven.plugins.fsm.maven.MavenCoordinate;
import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Build;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.*;
-import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
-import org.eclipse.aether.artifact.DefaultArtifact;
-import org.eclipse.aether.repository.LocalRepositoryManager;
-import org.eclipse.aether.resolution.ArtifactRequest;
-import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
+import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
+import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
/**
* Handles the resolution of an artifact within the maven reactor or repository.
@@ -42,26 +41,20 @@
* @since 1.0.0
*/
public class MavenGetArtifactsResolver implements IResolver {
+
private final Log log;
+ private final MavenSession session;
+ private final ArtifactResolver artifactResolver;
private final List reactorProjects;
- private final RepositorySystem repoSystem;
- private final RepositorySystemSession repoSession;
private final ProjectBuilder projectBuilder;
private final MavenProject parentMavenProject;
- /**
- * @param log The logger.
- * @param reactorProjects The projects within the reactor.
- * @param repoSystem The maven repository system.
- * @param repoSession The maven repository session.
- * @param projectBuilder The maven project builder.
- * @param parentMavenProject This maven project.
- */
- public MavenGetArtifactsResolver(final Log log, final List reactorProjects, final RepositorySystem repoSystem,
- final RepositorySystemSession repoSession, final ProjectBuilder projectBuilder, final MavenProject parentMavenProject) {
- this.repoSystem = repoSystem;
- this.repoSession = repoSession;
+ public MavenGetArtifactsResolver(final Log log, final MavenSession session, final ArtifactResolver artifactResolver,
+ final List reactorProjects, final ProjectBuilder projectBuilder,
+ final MavenProject parentMavenProject) {
this.log = log;
+ this.session = session;
+ this.artifactResolver = artifactResolver;
this.reactorProjects = reactorProjects;
this.projectBuilder = projectBuilder;
this.parentMavenProject = parentMavenProject;
@@ -70,33 +63,35 @@ public MavenGetArtifactsResolver(final Log log, final List reactor
/**
* {@inheritDoc}
*/
- public Module resolve(final ModuleType moduleType, final List scopes) throws MojoFailureException, MojoExecutionException {
- log.debug("Resolving module for dependency tag " + moduleType.getDependencyTagValueInXml());
- final Module module = new Module(log, moduleType, scopes);
- List mavenProjects = getMavenProjects(module);
- module.setProjects(mavenProjects);
- return module;
- }
-
- private List getMavenProjects(final Module module) throws MojoFailureException {
+ @Override
+ public List resolveMavenProjects(final List artifacts) {
List mavenProjects = new ArrayList<>();
- for (final DefaultArtifact artifactInfo : module.getArtifacts()) {
+ for (final MavenCoordinate artifactInfo : artifacts) {
+ // Order: reactor project, local project, maven repository
MavenProject mavenProject = getMavenProjectViaReactor(artifactInfo);
-
if (mavenProject != null) {
mavenProjects.add(mavenProject);
} else {
- log.debug("Module " + artifactInfo.getGroupId() + ":" + artifactInfo.getArtifactId()
- + " not found in reactor, trying to find it in the local repository.");
- mavenProjects.add(getMavenProjectViaRepository(artifactInfo));
+ mavenProject = getMavenProjectViaLocalWorkspace(artifactInfo);
+ if (mavenProject != null) {
+ mavenProjects.add(mavenProject);
+ } else {
+ // this succeeds or throws
+ mavenProjects.add(getMavenProjectViaRepository(artifactInfo));
+ }
}
}
- return mavenProjects;
+ return mavenProjects.stream().map(project -> {
+ project = project.clone();
+ // without an artifact filter, artifact resolution may fail
+ project.setArtifactFilter((a) -> true);
+ return project;
+ }).collect(Collectors.toList());
}
- private MavenProject getMavenProjectViaReactor(final DefaultArtifact artifact) {
+ private MavenProject getMavenProjectViaReactor(final MavenCoordinate artifact) {
MavenProject mavenProject = null;
boolean moduleInReactor = false;
@@ -117,27 +112,75 @@ private MavenProject getMavenProjectViaReactor(final DefaultArtifact artifact) {
return mavenProject;
}
- private MavenProject getMavenProjectViaRepository(final DefaultArtifact artifact) throws MojoFailureException {
+ private MavenProject getMavenProjectViaLocalWorkspace(final MavenCoordinate artifact) {
+ MavenProject rootProject = parentMavenProject.getParent();
+ if (rootProject != null && rootProject.getGroupId().equals(artifact.getGroupId())) {
+ log.debug("Module " + artifact.getGroupId() + ":" + artifact.getArtifactId()
+ + " might exist locally.");
+ File localArtifactPom = rootProject.getBasedir().toPath()
+ .resolve(artifact.getArtifactId()).resolve("pom.xml")
+ .toFile();
+ if (localArtifactPom.exists()) {
+ try {
+ MavenProject result = projectBuilder.build(localArtifactPom, buildingRequest()).getProject();
+ if (result != null) {
+ Build build = result.getBuild();
+ if (build != null) {
+ File artifactFile = new File(build.getDirectory()).toPath()
+ .resolve(build.getFinalName() + "." + result.getPackaging()).toFile();
+ if (artifactFile.exists()) {
+ result.getArtifact().setFile(artifactFile);
+ log.info("Resolved " + artifact + " via local project " + localArtifactPom.getPath());
+ return result;
+ }
+ }
+ }
+ } catch (ProjectBuildingException e) {
+ log.debug("Failed to build local project " + localArtifactPom + ".");
+ }
+ }
+ }
+ return null;
+ }
+
+ private ProjectBuildingRequest buildingRequest() {
+ return new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()).setResolveDependencies(true);
+ }
+
+ private Artifact coordinateToArtifact(MavenCoordinate artifactCoordinate) {
+ return coordinateToArtifact(artifactCoordinate, artifactCoordinate.getExtension());
+ }
+
+ private Artifact coordinateToArtifact(MavenCoordinate artifactCoordinate, String type) {
+ return new DefaultArtifact(artifactCoordinate.getGroupId(), artifactCoordinate.getArtifactId(),
+ artifactCoordinate.getVersion(), null, type,
+ artifactCoordinate.getClassifier(), new DefaultArtifactHandler(type));
+ }
+
+ private MavenProject getMavenProjectViaRepository(MavenCoordinate artifact) {
+ log.debug("Module " + artifact.getGroupId() + ":" + artifact.getArtifactId()
+ + " not found in reactor, trying to find it in the local repository.");
try {
- final ProjectBuildingRequest request = new DefaultProjectBuildingRequest()
- .setResolveDependencies(true)
- .setRemoteRepositories(parentMavenProject.getRemoteArtifactRepositories())
- .setRepositorySession(repoSession)
- .setSystemProperties(System.getProperties());
+ final ProjectBuildingRequest request = buildingRequest();
+ request.setProject(null);
- final LocalRepositoryManager localRepositoryManager = repoSession.getLocalRepositoryManager();
- final File repoBasedir = localRepositoryManager.getRepository().getBasedir();
+ final ArtifactRepository localRepository = session.getLocalRepository();
+ final File repoBasedir = new File(localRepository.getBasedir());
- // the module type artifact (war, jar, pom ...)
+ if ((artifact.getVersion() == null || artifact.getVersion().isEmpty())
+ && parentMavenProject.getGroupId().equals(artifact.getGroupId())) {
+ log.info("Assuming project version " + parentMavenProject.getVersion()
+ + " for artifact " + artifact);
+ artifact.setVersion(parentMavenProject.getVersion());
+ }
- final String pathForLocalArtifact = localRepositoryManager.getPathForLocalArtifact(artifact);
+ final String pathForLocalArtifact = localRepository.pathOf(coordinateToArtifact(artifact));
final File moduleArtifactFile = new File(repoBasedir, pathForLocalArtifact);
// the module pom artifact to build maven project
- final DefaultArtifact pomArtifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(),
- artifact.getClassifier(), "pom", artifact.getVersion());
+ final Artifact pomArtifact = coordinateToArtifact(artifact, "pom");
- final String localArtifactPath = localRepositoryManager.getPathForLocalArtifact(pomArtifact);
+ final String localArtifactPath = localRepository.pathOf(pomArtifact);
final File projectFile = new File(repoBasedir, localArtifactPath);
@@ -162,26 +205,30 @@ private MavenProject getMavenProjectViaRepository(final DefaultArtifact artifact
result.getArtifact().setFile(moduleArtifactFile);
result.setParent(parentMavenProject);
} else {
- throw new MojoFailureException("No dependency for " + artifact.getArtifactId() + " found in local or remote repository.");
+ throw new RuntimeException("No dependency for " + artifact.getArtifactId() + " found in local or remote repository.");
}
return result;
} catch (ProjectBuildingException e) {
- throw new MojoFailureException("No dependency for " + artifact.getArtifactId() + "found in local or remote repository.", e);
+ throw new RuntimeException("No dependency for " + artifact.getArtifactId() + " found in local or remote repository.", e);
}
}
- private void resolveArtifact(final DefaultArtifact moduleArtifact) throws MojoFailureException {
- log.info("Try to resolve artifact for " + moduleArtifact.getArtifactId() + " from remote repository...");
- final ArtifactRequest artifactRequest = new ArtifactRequest();
- artifactRequest.setArtifact(moduleArtifact);
- artifactRequest.setRepositories(parentMavenProject.getRemoteProjectRepositories());
-
+ private void resolveArtifact(final MavenCoordinate mavenCoordinate) {
+ log.info("Try to resolve artifact for " + mavenCoordinate.getArtifactId() + " from remote repository...");
+
+ DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
+ coordinate.setGroupId(mavenCoordinate.getGroupId());
+ coordinate.setArtifactId(mavenCoordinate.getArtifactId());
+ coordinate.setVersion(mavenCoordinate.getVersion());
+ coordinate.setExtension(mavenCoordinate.getExtension());
+ coordinate.setClassifier(mavenCoordinate.getClassifier());
+
try {
- repoSystem.resolveArtifact(repoSession, artifactRequest);
- } catch (ArtifactResolutionException e1) {
- throw new MojoFailureException("Could not resolve artifact " + moduleArtifact.getArtifactId() + ":" +
- moduleArtifact.getExtension() + " for maven project.", e1);
+ artifactResolver.resolveArtifact(buildingRequest(), coordinate);
+ } catch (ArtifactResolverException e) {
+ log.error("Failed to resolve artifact " + coordinate + ".");
+ throw new RuntimeException(e);
}
}
}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/FsmPluginConfigParser.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/FsmPluginConfigParser.java
new file mode 100644
index 0000000..f06ff07
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/FsmPluginConfigParser.java
@@ -0,0 +1,69 @@
+package com.monday_consulting.maven.plugins.fsm.xml;
+
+import com.monday_consulting.maven.plugins.fsm.jaxb.FsmMavenPluginType;
+import com.monday_consulting.maven.plugins.fsm.jaxb.ScopesType;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.File;
+import java.util.List;
+
+public class FsmPluginConfigParser {
+
+ private final Log log;
+
+ public FsmPluginConfigParser(Log log) {
+ this.log = log;
+ }
+
+ /**
+ * Validate a config-XML against the Plugin-XSD.
+ * Bind config-XML to generated POJOs.
+ *
+ * @param configXml The config-file to use
+ * @return WebformsMavenPluginType The corresponding Java-Object of the plugin-configuration.
+ * @throws MojoExecutionException in case of marshalling exception for the fsm-plugin.xsd.
+ */
+ public FsmMavenPluginType bindXmlConfigToPojo(final File configXml) throws MojoExecutionException {
+ log.debug("*** Constructing ConfigXml-Object");
+
+ try {
+ final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ final Schema schema = sf.newSchema(getClass().getResource("/fsm-plugin.xsd"));
+ final StreamSource streamSource = new StreamSource(configXml);
+ final JAXBContext jaxbContext = JAXBContext.newInstance(FsmMavenPluginType.class);
+ final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
+ unmarshaller.setSchema(schema);
+ unmarshaller.setEventHandler(new XmlValidationEventHandler(log));
+
+ final JAXBElement jaxbElement = unmarshaller.unmarshal(streamSource, FsmMavenPluginType.class);
+ FsmMavenPluginType config = jaxbElement.getValue();
+ applyDefaultConfiguration(config);
+ return config;
+ } catch (SAXException e) {
+ throw new MojoExecutionException(e, "Error while parsing file with SAX", e.getMessage());
+ } catch (JAXBException e) {
+ throw new MojoExecutionException(e, "Error while binding xml-file with JAXB", e.getMessage());
+ }
+ }
+
+ void applyDefaultConfiguration(FsmMavenPluginType config) {
+ if (config.getScopes() == null) {
+ ScopesType defaultScopesType = new ScopesType();
+ List defaultScopes = defaultScopesType.getScope();
+ defaultScopes.add("runtime");
+ defaultScopes.add("compile");
+ config.setScopes(defaultScopesType);
+ }
+ }
+
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/ModuleXmlWriter.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/ModuleXmlWriter.java
new file mode 100644
index 0000000..2029d11
--- /dev/null
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/ModuleXmlWriter.java
@@ -0,0 +1,70 @@
+package com.monday_consulting.maven.plugins.fsm.xml;
+
+import org.apache.maven.plugin.logging.Log;
+import org.codehaus.plexus.util.WriterFactory;
+import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XmlStreamWriter;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.Xpp3DomWriter;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class ModuleXmlWriter {
+
+ private final Log log;
+
+ public ModuleXmlWriter(Log log) {
+ this.log = log;
+ }
+
+ /**
+ * Write a DOM-Tree to a target directory.
+ * This will create {@code ./META-INF/module.xml} and {@code ./META-INF/module-isolated.xml}
+ *
+ * @param target target directory to write to
+ * @param dom dom to write to file.
+ * @throws IOException in case of unexpected writer exceptions.
+ */
+ public void writeDomToTarget(final Path target, final Xpp3Dom dom) throws IOException {
+ log.debug("Write TargetXml-File");
+
+ final Path metaInf = target.resolve("META-INF");
+ // ensure that the target directory exists
+ Files.createDirectories(metaInf);
+
+ final Path moduleXml = metaInf.resolve("module.xml");
+ log.info("Writing module descriptor: " + moduleXml);
+ writeFile(moduleXml.toFile(), dom);
+
+ final Path moduleIsolatedXml = metaInf.resolve("module-isolated.xml");
+ log.info("Writing isolated module descriptor: " + moduleIsolatedXml);
+ Files.copy(moduleXml, moduleIsolatedXml);
+
+ log.debug("Dependencies written to Module-XML:\n\t" + dom);
+ }
+
+ /**
+ * Write a DOM-Tree to a target XML file.
+ *
+ * @param target File to write to.
+ * @param dom dom to write to file.
+ * @throws IOException in case of unexpected writer exceptions.
+ */
+ public void writeDomToTarget(final File target, final Xpp3Dom dom) throws IOException {
+ log.info("Writing module descriptor: " + target.getAbsolutePath());
+
+ // ensure that the target directory exists
+ Files.createDirectories(target.toPath().getParent());
+ writeFile(target, dom);
+ }
+
+ private void writeFile(final File file, final Xpp3Dom dom) throws IOException {
+ final XmlStreamWriter writer = WriterFactory.newXmlWriter(file);
+ final PrettyPrintXMLWriter pretty = new PrettyPrintXMLWriter(writer);
+ Xpp3DomWriter.write(pretty, dom);
+ writer.close();
+ }
+}
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/PrototypeXml.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/PrototypeXml.java
similarity index 91%
rename from src/main/java/com/monday_consulting/maven/plugins/fsm/util/PrototypeXml.java
rename to src/main/java/com/monday_consulting/maven/plugins/fsm/xml/PrototypeXml.java
index 09a870c..df75479 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/PrototypeXml.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/PrototypeXml.java
@@ -1,4 +1,4 @@
-package com.monday_consulting.maven.plugins.fsm.util;
+package com.monday_consulting.maven.plugins.fsm.xml;
/*
Copyright 2016-2020 Monday Consulting GmbH
@@ -16,6 +16,7 @@
limitations under the License.
*/
+import com.monday_consulting.maven.plugins.fsm.util.Module;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
@@ -41,10 +42,15 @@ public class PrototypeXml {
private final List dependencyJointList;
private Xpp3Dom prototypeDom;
- public PrototypeXml(final Log log, final File prototypeXml) throws XmlPullParserException, IOException {
+ public PrototypeXml(final Log log, final File prototypeXml) {
this.dependencyJointList = new ArrayList<>();
this.log = log;
- this.prototypeDom = Xpp3DomBuilder.build(new XmlStreamReader(prototypeXml));
+
+ try {
+ this.prototypeDom = Xpp3DomBuilder.build(new XmlStreamReader(prototypeXml));
+ } catch (XmlPullParserException | IOException e) {
+ throw new RuntimeException("Failed to parse Module prototype " + prototypeXml, e);
+ }
if (log.isDebugEnabled()) {
this.log.debug("Getting dependency-joints\nDependency-Joints to fill:");
@@ -52,7 +58,7 @@ public PrototypeXml(final Log log, final File prototypeXml) throws XmlPullParser
for (final Xpp3Dom xpp3Dom : new Xpp3DomIterator(prototypeDom)) {
if (xpp3Dom.getName().equals("dependencies")) {
- if (xpp3Dom.getValue().equals("")) {
+ if (xpp3Dom.getValue().isEmpty()) {
log.error("Prototype-Xml-Error:\nTried to retrieve dependency-joint, but because its value was empty, no connection to a module can be made.");
}
dependencyJointList.add(new DependencyJoint(xpp3Dom.getValue(), xpp3Dom));
@@ -69,6 +75,8 @@ public PrototypeXml(final Log log, final File prototypeXml) throws XmlPullParser
* @throws MojoExecutionException in case of configuration problems.
*/
public void fillPrototypeDom(final Map moduleList) throws MojoExecutionException, MojoFailureException {
+ log.debug("Enhance Prototype for TargetXml");
+
for (final DependencyJoint dJ : dependencyJointList) {
Module moduleToInsert = moduleList.get(dJ.getDependencyTagValue());
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/XmlValidationEventHandler.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/XmlValidationEventHandler.java
similarity index 97%
rename from src/main/java/com/monday_consulting/maven/plugins/fsm/util/XmlValidationEventHandler.java
rename to src/main/java/com/monday_consulting/maven/plugins/fsm/xml/XmlValidationEventHandler.java
index c7eae80..5598bf4 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/XmlValidationEventHandler.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/XmlValidationEventHandler.java
@@ -1,4 +1,4 @@
-package com.monday_consulting.maven.plugins.fsm.util;
+package com.monday_consulting.maven.plugins.fsm.xml;
/*
Copyright 2016-2020 Monday Consulting GmbH
diff --git a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/Xpp3DomIterator.java b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/Xpp3DomIterator.java
similarity index 98%
rename from src/main/java/com/monday_consulting/maven/plugins/fsm/util/Xpp3DomIterator.java
rename to src/main/java/com/monday_consulting/maven/plugins/fsm/xml/Xpp3DomIterator.java
index eb67a90..1eb53d5 100644
--- a/src/main/java/com/monday_consulting/maven/plugins/fsm/util/Xpp3DomIterator.java
+++ b/src/main/java/com/monday_consulting/maven/plugins/fsm/xml/Xpp3DomIterator.java
@@ -1,4 +1,4 @@
-package com.monday_consulting.maven.plugins.fsm.util;
+package com.monday_consulting.maven.plugins.fsm.xml;
/*
Copyright 2016-2020 Monday Consulting GmbH
diff --git a/src/main/resources/fsm-plugin.xsd b/src/main/resources/fsm-plugin.xsd
index 6c9c443..5f70e8b 100644
--- a/src/main/resources/fsm-plugin.xsd
+++ b/src/main/resources/fsm-plugin.xsd
@@ -42,7 +42,7 @@
-
+
diff --git a/src/test/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojoTest.java b/src/test/java/com/monday_consulting/maven/plugins/fsm/xml/FsmPluginConfigParserTest.java
similarity index 73%
rename from src/test/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojoTest.java
rename to src/test/java/com/monday_consulting/maven/plugins/fsm/xml/FsmPluginConfigParserTest.java
index bdf2b78..417b489 100644
--- a/src/test/java/com/monday_consulting/maven/plugins/fsm/DependencyToXMLMojoTest.java
+++ b/src/test/java/com/monday_consulting/maven/plugins/fsm/xml/FsmPluginConfigParserTest.java
@@ -1,15 +1,17 @@
-package com.monday_consulting.maven.plugins.fsm;
+package com.monday_consulting.maven.plugins.fsm.xml;
import com.monday_consulting.maven.plugins.fsm.jaxb.FsmMavenPluginType;
import com.monday_consulting.maven.plugins.fsm.jaxb.ModuleType;
import com.monday_consulting.maven.plugins.fsm.jaxb.ModulesType;
+import org.apache.maven.plugin.logging.Log;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
-class DependencyToXMLMojoTest {
+class FsmPluginConfigParserTest {
@Test
void applyDefaultConfiguration() {
@@ -20,15 +22,12 @@ void applyDefaultConfiguration() {
config.setModules(modulesType);
// apply default config
- DependencyToXMLMojo mojo = new DependencyToXMLMojo();
- mojo.applyDefaultConfiguration(config);
+ FsmPluginConfigParser configParser = new FsmPluginConfigParser(mock(Log.class));
+ configParser.applyDefaultConfiguration(config);
// validate config
final List defaultScopes = config.getScopes().getScope();
assertTrue(defaultScopes.contains("runtime"), "'runtime' should be a default scope");
assertTrue(defaultScopes.contains("compile"), "'compile' should be a default scope");
-
- String prefix = config.getModules().getModule().get(0).getPrefix();
- assertEquals("", prefix, "Config should have an empty prefix");
}
}