You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2024/09/12 15:05:55 UTC
(maven-hocon-extension) branch main created (now 2fa97fa)
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/maven-hocon-extension.git
at 2fa97fa Hocon extension
This branch includes the following new commits:
new 2fa97fa Hocon extension
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(maven-hocon-extension) 01/01: Hocon extension
Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/maven-hocon-extension.git
commit 2fa97fad15db1ce560f76417a1b7f0905f0be708
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Thu Sep 12 17:00:21 2024 +0200
Hocon extension
---
.github/dependabot.yml | 28 +++
.github/workflows/maven-verify.yml | 31 ++++
.gitignore | 18 ++
README.md | 64 +++++++
pom.xml | 185 ++++++++++++++++++
src/it/hocon-example/.mvn/extensions.xml | 26 +++
src/it/hocon-example/child/pom.hocon | 35 ++++
src/it/hocon-example/pom.xml | 34 ++++
src/it/settings.xml | 25 +++
.../org/apache/maven/hocon/HoconModelParser.java | 63 +++++++
.../java/org/apache/maven/hocon/PathSource.java | 56 ++++++
src/main/resources/META-INF/maven/extension.xml | 27 +++
.../META-INF/maven/org.apache.maven.api.di.Inject | 17 ++
src/mdo/hocon-reader.vm | 206 +++++++++++++++++++++
.../java/org/apache/maven/hocon/ParsingTest.java | 42 +++++
src/test/resources/pom.hocon | 36 ++++
16 files changed, 893 insertions(+)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..ce41a74
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,28 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+version: 2
+updates:
+
+ - package-ecosystem: maven
+ directory: "/"
+ schedule:
+ interval: daily
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
\ No newline at end of file
diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml
new file mode 100644
index 0000000..99811aa
--- /dev/null
+++ b/.github/workflows/maven-verify.yml
@@ -0,0 +1,31 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+name: Verify
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ build:
+ name: Verify
+ uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v4
+ with:
+ ff-maven: "4.0.0-beta-4" # Maven version for fail-fast-build
+ maven-matrix: '[ "4.0.0-beta-4" ]'
+ jdk-matrix: '[ "17", "21" ]'
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e6cbeac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+**/target/**
+.project
+.classpath
+.settings/
+.svn/
+# Intellij
+*.ipr
+*.iml
+.idea
+.DS_Store
+/bootstrap
+/dependencies.xml
+.java-version
+.checkstyle
+.factorypath
+.vscode/
+repo/
+/*.svg
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7c8a2eb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,64 @@
+<!---
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+[Apache Maven Hocon Extension](https://maven.apache.org/extensions/maven-xinclude-extension/)
+==================================
+
+[](https://www.apache.org/licenses/LICENSE-2.0)
+[](https://search.maven.org/artifact/org.apache.maven.extensions/maven-xinclude-extension)
+
+This project provides a Hocon POM parser extension for Maven 4. It allows POMs to
+be written with the [Hocon](https://github.com/lightbend/config/blob/master/HOCON.md)
+syntax, which is a superset of the [JSON](https://json.org/) syntax.
+
+License
+-------
+This code is under the [Apache License, Version 2.0, January 2004][license].
+
+See the [`NOTICE`](./NOTICE) file for required notices and attributions.
+
+Usage
+-----
+To use this extension, the following declaration needs to be done in your `${rootDirectory}/.mvn/extensions.xml`:
+```
+<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.2.0">
+ <extension>
+ <groupId>org.apache.maven.extensions</groupId>
+ <artifactId>maven-hocon-extension</artifactId>
+ <version>@project.version@</version>
+ </extension>
+</extensions>
+```
+This allows defining a POM using Hocon syntax:
+```
+modelVersion = 4.1.0
+parent {
+ groupId = org.apache.maven.hocon.its
+ artifactId = parent
+ version = 1.0.0-SNAPSHOT
+}
+artifactId = test
+
+properties = {
+ "my.property" = foo
+ pluginVersion = 3.9
+}
+
+dependencies = [
+ # just add one dummy dependency
+ "com.typesafe:config:1.4.2"
+]
+```
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..fc29277
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.maven.extensions</groupId>
+ <artifactId>maven-extensions</artifactId>
+ <version>43</version>
+ <relativePath />
+ </parent>
+
+ <artifactId>maven-hocon-extension</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <name>Hocon extension for Maven 4</name>
+ <description>Provides Hocon syntax support</description>
+
+ <properties>
+ <javaVersion>17</javaVersion>
+ <maven.version>4.0.0-beta-4</maven.version>
+ <junit.version>5.11.0</junit.version>
+ <hocon.version>1.4.2</hocon.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-api-spi</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-api-core</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-api-di</artifactId>
+ <version>${maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-api-impl</artifactId>
+ <version>${maven.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.typesafe</groupId>
+ <artifactId>config</artifactId>
+ <version>${hocon.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.junit.jupiter</groupId>
+ <artifactId>junit-jupiter</artifactId>
+ <version>${junit.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <version>3.3.0</version>
+ <!-- Use the latest version of the plugin -->
+ <executions>
+ <execution>
+ <id>enforce-maven</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireMavenVersion>
+ <version>[4.0.0-beta-4,)</version>
+ <!-- Specify the required Maven version -->
+ <message>You need Maven 4.0.0-beta-4 or higher to build this project.</message>
+ </requireMavenVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>3.7.1</version>
+ <executions>
+ <execution>
+ <id>copy-mdo</id>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <phase>generate-sources</phase>
+ <configuration>
+ <outputDirectory>${project.build.directory}/mdo</outputDirectory>
+ <artifact>org.apache.maven:maven-api-model:${maven.version}:mdo</artifact>
+ <stripVersion>true</stripVersion>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.modello</groupId>
+ <artifactId>modello-maven-plugin</artifactId>
+ <version>2.4.0</version>
+ <executions>
+ <execution>
+ <id>generate-hocon-reader</id>
+ <goals>
+ <goal>velocity</goal>
+ </goals>
+ <phase>generate-sources</phase>
+ <configuration>
+ <version>4.2.0</version>
+ <models>
+ <model>target/mdo/maven-api-model.mdo</model>
+ </models>
+ <templates>
+ <template>src/mdo/hocon-reader.vm</template>
+ </templates>
+ <params>
+ <param>packageModelV4=org.apache.maven.api.model</param>
+ </params>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.11.0</version>
+ <configuration>
+ <release>${javaVersion}</release>
+ <proc>full</proc>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>run-its</id>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-invoker-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <showErrors>true</showErrors>
+ <cloneProjectsTo>${project.build.directory}/its</cloneProjectsTo>
+ <cloneClean>true</cloneClean>
+ <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
+ <settingsFile>src/it/settings.xml</settingsFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
diff --git a/src/it/hocon-example/.mvn/extensions.xml b/src/it/hocon-example/.mvn/extensions.xml
new file mode 100644
index 0000000..90ec8fc
--- /dev/null
+++ b/src/it/hocon-example/.mvn/extensions.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.2.0 https://maven.apache.org/xsd/core-extensions-1.2.0.xsd">
+ <extension>
+ <groupId>org.apache.maven.extensions</groupId>
+ <artifactId>maven-hocon-extension</artifactId>
+ <version>@project.version@</version>
+ </extension>
+</extensions>
\ No newline at end of file
diff --git a/src/it/hocon-example/child/pom.hocon b/src/it/hocon-example/child/pom.hocon
new file mode 100644
index 0000000..97c8295
--- /dev/null
+++ b/src/it/hocon-example/child/pom.hocon
@@ -0,0 +1,35 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+modelVersion = 4.1.0
+parent {
+ groupId = org.apache.maven.hocon.its
+ artifactId = parent
+ version = 1.0.0-SNAPSHOT
+}
+artifactId = test
+
+properties = {
+ "my.property" = foo
+ pluginVersion = 3.9
+}
+
+dependencies = [
+ # just add one dummy dependency
+ "com.typesafe:config:1.4.2"
+]
\ No newline at end of file
diff --git a/src/it/hocon-example/pom.xml b/src/it/hocon-example/pom.xml
new file mode 100644
index 0000000..c2c98ac
--- /dev/null
+++ b/src/it/hocon-example/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 http://maven.apache.org/xsd/maven-4.1.0.xsd">
+ <parent>
+ <groupId>org.apache.maven.extensions</groupId>
+ <artifactId>maven-extensions</artifactId>
+ <version>43</version>
+ </parent>
+ <groupId>org.apache.maven.hocon.its</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>child</module>
+ </modules>
+</project>
diff --git a/src/it/settings.xml b/src/it/settings.xml
new file mode 100644
index 0000000..0317296
--- /dev/null
+++ b/src/it/settings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<settings xmlns="http://maven.apache.org/SETTINGS/1.3.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.3.0 https://maven.apache.org/xsd/settings-1.3.0.xsd">
+</settings>
\ No newline at end of file
diff --git a/src/main/java/org/apache/maven/hocon/HoconModelParser.java b/src/main/java/org/apache/maven/hocon/HoconModelParser.java
new file mode 100644
index 0000000..fb3cb68
--- /dev/null
+++ b/src/main/java/org/apache/maven/hocon/HoconModelParser.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.hocon;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Optional;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import org.apache.maven.api.di.Named;
+import org.apache.maven.api.di.Priority;
+import org.apache.maven.api.model.Model;
+import org.apache.maven.api.services.Source;
+import org.apache.maven.api.spi.ModelParser;
+import org.apache.maven.api.spi.ModelParserException;
+
+@Named("hocon")
+@Priority(10)
+public class HoconModelParser implements ModelParser {
+
+ @Override
+ public Optional<Source> locate(Path path) {
+ Path pom = Files.isDirectory(path) ? path.resolve("pom.hocon") : path;
+ return Files.isRegularFile(pom) ? Optional.of(new PathSource(pom)) : Optional.empty();
+ }
+
+ @Override
+ public Model parse(Source source, Map<String, ?> map) throws ModelParserException {
+ Config config;
+ if (source.getPath() != null) {
+ config = ConfigFactory.parseFile(source.getPath().toFile());
+ } else {
+ try (InputStream input = source.openStream()) {
+ config = ConfigFactory.parseReader(new InputStreamReader(input, StandardCharsets.UTF_8));
+ } catch (IOException e) {
+ throw new ModelParserException("Unable to parse: " + source.getLocation(), e);
+ }
+ }
+ return new HoconReader().parseModel(config.root());
+ }
+}
diff --git a/src/main/java/org/apache/maven/hocon/PathSource.java b/src/main/java/org/apache/maven/hocon/PathSource.java
new file mode 100644
index 0000000..cdf5b7b
--- /dev/null
+++ b/src/main/java/org/apache/maven/hocon/PathSource.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.hocon;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Objects;
+
+import org.apache.maven.api.services.Source;
+
+public class PathSource implements Source {
+
+ private final Path path;
+
+ public PathSource(Path path) {
+ this.path = Objects.requireNonNull(path);
+ }
+
+ @Override
+ public Path getPath() {
+ return path;
+ }
+
+ @Override
+ public InputStream openStream() throws IOException {
+ return Files.newInputStream(path);
+ }
+
+ @Override
+ public String getLocation() {
+ return path.toString();
+ }
+
+ @Override
+ public Source resolve(String s) {
+ return new PathSource(path.resolve(s));
+ }
+}
diff --git a/src/main/resources/META-INF/maven/extension.xml b/src/main/resources/META-INF/maven/extension.xml
new file mode 100644
index 0000000..77ffe86
--- /dev/null
+++ b/src/main/resources/META-INF/maven/extension.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<!-- START SNIPPET: core-extension -->
+<extension>
+ <exportedPackages>
+ <exportedPackage>org.apache.maven.hocon</exportedPackage>
+ <exportedPackage>META-INF.maven</exportedPackage>
+ </exportedPackages>
+</extension>
\ No newline at end of file
diff --git a/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject b/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject
new file mode 100644
index 0000000..6778661
--- /dev/null
+++ b/src/main/resources/META-INF/maven/org.apache.maven.api.di.Inject
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+org.apache.maven.hocon.HoconModelParser
diff --git a/src/mdo/hocon-reader.vm b/src/mdo/hocon-reader.vm
new file mode 100644
index 0000000..b21925f
--- /dev/null
+++ b/src/mdo/hocon-reader.vm
@@ -0,0 +1,206 @@
+#*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*#
+#set ( $package = "org.apache.maven.hocon" )
+#set ( $className = "HoconReader" )
+#
+#set ( $root = $model.getClass( $model.getRoot($version), $version ) )
+#set ( $rootXml = $Helper.xmlClassMetadata( $root ) )
+#set ( $rootTag = $rootXml.tagName )
+#set ( $rootUcapName = $Helper.capitalise( $root.name ) )
+#set ( $rootLcapName = $Helper.uncapitalise( $root.name ) )
+#
+#MODELLO-VELOCITY#SAVE-OUTPUT-TO ${package.replace('.','/')}/${className}.java
+// =================== DO NOT EDIT THIS FILE ====================
+// Generated by Modello Velocity from ${template}
+// template, any modifications will be overwritten.
+// ==============================================================
+package ${package};
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import org.apache.maven.api.annotations.Generated;
+#foreach ( $class in $model.allClasses )
+import ${packageModelV4}.${class.name};
+#end
+import com.typesafe.config.ConfigList;
+import com.typesafe.config.ConfigObject;
+import com.typesafe.config.ConfigValue;
+import com.typesafe.config.ConfigValueType;
+
+@Generated
+public class ${className} {
+
+#foreach ( $class in $model.allClasses )
+ #if ( $class.name != "InputSource" && $class.name != "InputLocation" )
+ #set ( $classUcapName = $Helper.capitalise( $class.name ) )
+ #set ( $classLcapName = $Helper.uncapitalise( $class.name ) )
+ #set ( $ancestors = $Helper.ancestors( $class ) )
+ #set ( $allFields = [] )
+ #foreach ( $cl in $ancestors )
+ #set ( $dummy = $allFields.addAll( $cl.getFields($version) ) )
+ #end
+ public ${classUcapName} parse${classUcapName}(ConfigValue value) {
+ if (value instanceof ConfigObject) {
+ ${classUcapName}.Builder ${classLcapName} = ${classUcapName}.newBuilder(true);
+ ((ConfigObject) value).forEach((k, v) -> {
+ switch (k) {
+ #foreach ( $field in $allFields )
+ #if ( ! $Helper.xmlFieldMetadata( $field ).transient && $field.name != "root" )
+ #set ( $fieldTagName = $Helper.xmlFieldMetadata( $field ).tagName )
+ #if ( ! $fieldTagName )
+ #set ( $fieldTagName = $field.name )
+ #end
+ #if ( $Helper.isFlatItems( $field ) )
+ #set ( $fieldTagName = $Helper.singular( $fieldTagName ) )
+ #end
+ #set ( $fieldCapName = $Helper.capitalise( $field.name ) )
+ case "${fieldTagName}": {
+ #if ( $field.type == "String" )
+ ${classLcapName}.${field.name}(getStringValue(v));
+ break;
+ #elseif ( $field.type == "boolean" || $field.type == "Boolean" )
+ ${classLcapName}.${field.name}(getBooleanValue(v));
+ break;
+ #elseif ( $field.type == "int" )
+ ${classLcapName}.${field.name}(getIntegerValue(v));
+ break;
+ #elseif ( $field.type == "DOM" )
+// ${classLcapName}.${field.name}(XmlNodeBuilder.build(parser, true));
+ break;
+ #elseif ( $field.type == "java.util.List" && $field.to == "String" && $field.multiplicity == "*" )
+ ${classLcapName}.${field.name}(getStringList(v));
+ break;
+ #elseif ( $field.type == "java.util.Properties" && $field.to == "String" && $field.multiplicity == "*" )
+ ${classLcapName}.${field.name}(getStringMap(v));
+ break;
+ #elseif ( $field.to && $field.multiplicity == "1" )
+ ${classLcapName}.${field.name}(parse${field.toClass.name}(v));
+ break;
+ #elseif ( $field.to && $field.multiplicity == "*" && $Helper.isFlatItems( $field ) )
+ ${field.name}.add(parse${field.toClass.name}(v));
+ break;
+ #elseif ( $field.to && $field.multiplicity == "*" )
+ ${classLcapName}.${field.name}(getList(v, this::parse${field.toClass.name}));
+ break;
+ #else
+ // TODO: type=${field.type} to=${field.to} multiplicity=${field.multiplicity}
+ break;
+ #end
+ }
+ #end
+ #end
+ default: {
+ checkUnknownElement(k, v);
+ break;
+ }
+ }
+ });
+ #foreach ( $field in $allFields )
+ #if ( $Helper.isFlatItems( $field ) )
+ ${classLcapName}.${field.name}(${field.name});
+ #end
+ #end
+ return ${classLcapName}.build();
+ #if($class.name=="Dependency")
+ } else if (value != null && value.valueType() == ConfigValueType.STRING) {
+ Dependency.Builder dependency = Dependency.newBuilder(true);
+ String[] tokens = ((String) value.unwrapped()).split(":");
+ if (tokens.length < 3 || tokens.length > 5) {
+ throw new RuntimeException("Invalid artifact, you must specify "
+ + "groupId:artifactId:version[:packaging[:classifier]] " + value);
+ }
+ dependency.groupId(tokens[0]);
+ dependency.artifactId(tokens[1]);
+ dependency.version(tokens[2]);
+ if (tokens.length >= 4) {
+ dependency.type(tokens[3]);
+ }
+ if (tokens.length == 5) {
+ dependency.classifier(tokens[4]);
+ }
+ return dependency.build();
+ #end
+ } else if (value != null) {
+ throw new IllegalArgumentException("Invalid syntax: cannot parse: " + value);
+ }
+ return null;
+ }
+
+ #end
+#end
+
+ protected String getStringValue(ConfigValue v) {
+ return v.unwrapped().toString();
+ }
+
+ protected List<String> getStringList(ConfigValue v) {
+ if (v instanceof ConfigList) {
+ return ((ConfigList) v).unwrapped().stream().map(Object::toString)
+ .collect(Collectors.toList());
+ }
+ throw new IllegalArgumentException("Unable to convert to List<String>: '" + v + "'");
+ }
+
+ protected boolean getBooleanValue(ConfigValue v) {
+ return Boolean.parseBoolean(v.unwrapped().toString());
+ }
+
+ protected int getIntegerValue(ConfigValue v) {
+ return Integer.parseInt(v.unwrapped().toString());
+ }
+
+ protected ConfigList getList(ConfigValue v) {
+ if (v instanceof ConfigList) {
+ return (ConfigList) v;
+ }
+ throw new IllegalArgumentException("Unable to convert to List<?>: '" + v + "'");
+ }
+
+ protected <T> List<T> getList(ConfigValue v, Function<ConfigValue, T> parser) {
+ return getList(v).stream().map(parser).collect(Collectors.toList());
+ }
+
+ protected Map<String, String> getStringMap(ConfigValue v) {
+ if (v instanceof ConfigObject) {
+ return ((ConfigObject) v).entrySet().stream().collect(Collectors.toMap(
+ e -> e.getKey(),
+ e -> getStringValue(e.getValue())
+ ));
+ }
+ throw new IllegalArgumentException("Unable to convert to Map<String, String>: '" + v + "'");
+ }
+
+ protected void checkUnknownElement(String k, Object v) {
+ throw new IllegalArgumentException("Unrecognized element '" + k + "' with value '" + v + "'");
+ }
+
+}
diff --git a/src/test/java/org/apache/maven/hocon/ParsingTest.java b/src/test/java/org/apache/maven/hocon/ParsingTest.java
new file mode 100644
index 0000000..6f611af
--- /dev/null
+++ b/src/test/java/org/apache/maven/hocon/ParsingTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.hocon;
+
+import java.io.File;
+
+import com.typesafe.config.Config;
+import com.typesafe.config.ConfigFactory;
+import org.apache.maven.api.model.Model;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ParsingTest {
+
+ @Test
+ void testParse() throws Exception {
+ Config config = ConfigFactory.parseFile(new File("src/test/resources/pom.hocon"));
+
+ Model model = new HoconReader().parseModel(config.root());
+
+ assertEquals("40", model.getParent().getVersion());
+ assertEquals(1, model.getDependencies().size());
+ assertEquals(2, model.getProperties().size());
+ }
+}
diff --git a/src/test/resources/pom.hocon b/src/test/resources/pom.hocon
new file mode 100644
index 0000000..c51b554
--- /dev/null
+++ b/src/test/resources/pom.hocon
@@ -0,0 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+modelVersion = 4.0.0
+parent {
+ groupId = org.apache.maven.extensions
+ artifactId = maven-extensions
+ version = 40
+}
+groupId = org.apache.maven.extensions
+artifactId = maven-hocon-extension
+version = 1.0.0-SNAPSHOT
+
+properties = {
+ "my.property" = foo
+ pluginVersion = 3.9
+}
+
+dependencies = [
+ { groupId = org.apache.maven, artifactId = maven-api-core, version = 4.0.0-alpha-8-SNAPSHOT }
+]
\ No newline at end of file