mirror of
https://github.com/apple/pkl.git
synced 2026-01-16 00:23:44 +01:00
Initial commit
This commit is contained in:
22
docs/modules/java-binding/examples/JavaConfigExample.java
Normal file
22
docs/modules/java-binding/examples/JavaConfigExample.java
Normal file
@@ -0,0 +1,22 @@
|
||||
import org.pkl.config.java.Config;
|
||||
import org.pkl.config.java.ConfigEvaluator;
|
||||
import org.pkl.config.java.JavaType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
// the pkl/pkl-examples repo has a similar example
|
||||
public class JavaConfigExample {
|
||||
@Test
|
||||
public void usage() {
|
||||
// tag::usage[]
|
||||
Config config;
|
||||
try (var evaluator = ConfigEvaluator.preconfigured()) { // <1>
|
||||
config = evaluator.evaluateText(
|
||||
"pigeon { age = 5; diet = \"Seeds\" }"); // <2>
|
||||
}
|
||||
var pigeon = config.get("pigeon"); // <3>
|
||||
var age = pigeon.get("age").as(int.class); // <4>
|
||||
var diet = pigeon.get("diet").as(JavaType.listOf(String.class)); // <5>
|
||||
// end::usage[]
|
||||
}
|
||||
}
|
||||
180
docs/modules/java-binding/pages/codegen.adoc
Normal file
180
docs/modules/java-binding/pages/codegen.adoc
Normal file
@@ -0,0 +1,180 @@
|
||||
= Java Code Generator
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-codgen-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-codegen-java
|
||||
|
||||
The Java source code generator takes Pkl class definitions as an input, and generates corresponding Java classes with equally named properties.
|
||||
|
||||
The benefits of code generation are:
|
||||
|
||||
* Configuration can be conveniently consumed as statically typed Java objects.
|
||||
* The entire configuration tree can be code-completed in Java IDEs.
|
||||
* Any drift between Java code and Pkl configuration structure is caught at compile time.
|
||||
|
||||
The generated classes are immutable and have component-wise implementations of `equals()`, `hashCode()`, and `toString()`.
|
||||
|
||||
== Installation
|
||||
|
||||
The code generator is offered as Gradle plugin, Java library, and CLI.
|
||||
|
||||
=== Gradle Plugin
|
||||
|
||||
See xref:pkl-gradle:index.adoc#installation[Installation] in the Gradle plugin chapter.
|
||||
|
||||
[[install-library]]
|
||||
=== Java Library
|
||||
|
||||
The `pkl-codegen-java` library is available {uri-pkl-codgen-java-maven-module}[from Maven Central].
|
||||
It requires Java 11 or higher.
|
||||
|
||||
ifndef::is-release-version[]
|
||||
NOTE: Snapshots are published to repository `{uri-sonatype}`.
|
||||
endif::[]
|
||||
|
||||
==== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-codegen-java:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-codegen-java:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
==== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<project>
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-codegen-java</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</dependency>
|
||||
ifndef::is-release-build[]
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-s01</id>
|
||||
<name>Sonatype S01</name>
|
||||
<url>{uri-sonatype}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
endif::[]
|
||||
</project>
|
||||
----
|
||||
|
||||
[[install-cli]]
|
||||
=== CLI
|
||||
|
||||
The CLI is bundled with the Java library.
|
||||
As we do not currently ship the CLI as a self-contained Jar, we recommend to provision it with a Maven compatible build tool as shown in <<install-library>>.
|
||||
|
||||
[[codegen-java-usage]]
|
||||
== Usage
|
||||
|
||||
The code generator is offered as Gradle plugin, Java library, and CLI.
|
||||
|
||||
=== Gradle Plugin
|
||||
|
||||
See xref:pkl-gradle:index.adoc#java-code-gen[Java Code Generation] in the Gradle plugin chapter.
|
||||
|
||||
=== Java Library
|
||||
|
||||
The Java library offers two APIs: a high-level API that corresponds to the CLI, and a lower-level API that provides additional features and control.
|
||||
The entry points for these APIs are `org.pkl.codegen.java.CliJavaCodeGenerator` and `org.pkl.codegen.java.JavaCodeGenerator`, respectively.
|
||||
For more information, refer to the Javadoc documentation.
|
||||
|
||||
=== CLI
|
||||
|
||||
As explained in <<install-cli,Installation>>, the CLI is bundled with the Java library.
|
||||
To run the CLI, execute the library Jar or its `org.pkl.codegen.java.Main` main class.
|
||||
|
||||
*Synopsis:* `java -cp <classpath> -jar pkl-codegen-java.jar [<options>] <modules>`
|
||||
|
||||
`<modules>`::
|
||||
The absolute or relative URIs of the modules to generate classes for.
|
||||
Relative URIs are resolved against the working directory.
|
||||
|
||||
==== Options
|
||||
|
||||
.--generate-getters
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate private final fields and public getter methods instead of public final fields.
|
||||
====
|
||||
|
||||
.--generate-javadoc
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Flag that indicates to generate Javadoc based on doc comments for Pkl modules, classes, and properties.
|
||||
====
|
||||
|
||||
.--params-annotation
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `org.pkl.config.java.mapper.Named` +
|
||||
Fully qualified name of the annotation to use on constructor parameters.
|
||||
====
|
||||
|
||||
.--non-null-annotation
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `org.pkl.config.java.mapper.NonNull` +
|
||||
Fully qualified named of the annotation class to use for non-null types. +
|
||||
This annotation is required to have `java.lang.annotation.ElementType.TYPE_USE` as a `@Target`
|
||||
or it may generate code that does not compile.
|
||||
====
|
||||
|
||||
.--implement-serializable
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (flag not set) +
|
||||
Whether to make generated classes implement `java.io.Serializable`.
|
||||
====
|
||||
|
||||
Common code generator options:
|
||||
|
||||
include::{partialsdir}/cli-codegen-options.adoc[]
|
||||
|
||||
Common CLI options:
|
||||
|
||||
include::../../pkl-cli/partials/cli-common-options.adoc[]
|
||||
|
||||
[[full-example]]
|
||||
== Full Example
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-codegen-java-example}[codegen-java] in the _pkl/pkl-examples_ repository.
|
||||
4
docs/modules/java-binding/pages/index.adoc
Normal file
4
docs/modules/java-binding/pages/index.adoc
Normal file
@@ -0,0 +1,4 @@
|
||||
= Integration with Java
|
||||
|
||||
Pkl provides rich integration with Java. Our integration allows you to embed the Pkl runtime into your Java program, and also provides code generation from Pkl source files.
|
||||
|
||||
212
docs/modules/java-binding/pages/pkl-config-java.adoc
Normal file
212
docs/modules/java-binding/pages/pkl-config-java.adoc
Normal file
@@ -0,0 +1,212 @@
|
||||
= pkl-config-java Library
|
||||
include::ROOT:partial$component-attributes.adoc[]
|
||||
:uri-pkl-core-EvalException: {uri-pkl-core-main-sources}/EvalException.java
|
||||
|
||||
:uri-pkl-config-java-maven-module: {uri-maven-docsite}/artifact/org.pkl-lang/pkl-config-java-all
|
||||
:uri-pkl-config-java-main-sources: {uri-github-tree}/pkl-config-java/src/main/java/org/pkl/config/java
|
||||
:uri-pkl-config-java-test-sources: {uri-github-tree}/pkl-config-java/src/test/java/org/pkl/config/java
|
||||
:uri-pkl-config-java-test-resources: {uri-github-tree}/pkl-config-java/src/test/resources/org/pkl/config/java
|
||||
:uri-pkl-config-java-ConfigEvaluator: {uri-pkl-config-java-main-sources}/ConfigEvaluator.java
|
||||
:uri-pkl-config-java-Config: {uri-pkl-config-java-main-sources}/Config.java
|
||||
:uri-pkl-config-java-ValueMapper: {uri-pkl-config-java-main-sources}/mapper/ValueMapper.java
|
||||
:uri-pkl-config-java-Named: {uri-pkl-config-java-main-sources}/mapper/Named.java
|
||||
:uri-pkl-config-java-Conversion: {uri-pkl-config-java-main-sources}/mapper/Conversion.java
|
||||
:uri-pkl-config-java-Conversions: {uri-pkl-config-java-main-sources}/mapper/Conversions.java
|
||||
:uri-pkl-config-java-ConverterFactories: {uri-pkl-config-java-main-sources}/mapper/ConverterFactories.java
|
||||
:uri-pkl-config-java-Converter: {uri-pkl-config-java-main-sources}/mapper/Converter.java
|
||||
:uri-pkl-config-java-ConverterFactory: {uri-pkl-config-java-main-sources}/mapper/ConverterFactory.java
|
||||
:uri-pkl-config-java-PObjectToObjectByCtorTestJava: {uri-pkl-config-java-test-sources}/mapper/PObjectToObjectByCtorTest.java
|
||||
:uri-pkl-config-java-PObjectToObjectByCtorTestPkl: {uri-pkl-config-java-test-resources}/mapper/PObjectToObjectByCtorTest.pkl
|
||||
|
||||
The _pkl-config-java_ library builds upon xref:pkl-core:index.adoc[pkl-core].
|
||||
It offers a higher-level API specifically designed for consuming application runtime configuration.
|
||||
|
||||
== Installation
|
||||
|
||||
The _pkl-config-java_ library is available {uri-pkl-config-java-maven-module}[from Maven Central].
|
||||
It requires Java 11 or higher.
|
||||
|
||||
=== Gradle
|
||||
|
||||
To use the library in a Gradle project, declare the following dependency:
|
||||
|
||||
[tabs]
|
||||
====
|
||||
Groovy::
|
||||
+
|
||||
.build.gradle
|
||||
[source,groovy,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile "org.pkl-lang:pkl-config-java:{pkl-artifact-version}"
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url "{uri-sonatype}" }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
.build.gradle.kts
|
||||
[source,kotlin,subs="+attributes"]
|
||||
----
|
||||
dependencies {
|
||||
compile("org.pkl-lang:pkl-config-java:{pkl-artifact-version}")
|
||||
}
|
||||
|
||||
ifndef::is-release-build[]
|
||||
repositories {
|
||||
maven { url = uri("{uri-sonatype}") }
|
||||
}
|
||||
endif::[]
|
||||
----
|
||||
====
|
||||
|
||||
Unlike `pkl-config-java`, `pkl-config-java__-all__` is a fat Jar with renamed third-party packages to avoid version conflicts.
|
||||
|
||||
=== Maven
|
||||
|
||||
To use the library in a Maven project, declare the following dependency:
|
||||
|
||||
.pom.xml
|
||||
[source,xml,subs="+attributes"]
|
||||
----
|
||||
<project>
|
||||
<dependency>
|
||||
<groupId>org.pkl-lang</groupId>
|
||||
<artifactId>pkl-config-java</artifactId>
|
||||
<version>{pkl-artifact-version}</version>
|
||||
</dependency>
|
||||
ifndef::is-release-build[]
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype-s01</id>
|
||||
<name>Sonatype S01</name>
|
||||
<url>{uri-sonatype}</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
endif::[]
|
||||
</project>
|
||||
----
|
||||
|
||||
Unlike `pkl-config-java`, `pkl-config-java__-all__` is a fat Jar with renamed third-party packages to avoid version conflicts.
|
||||
|
||||
== Usage
|
||||
|
||||
=== Consuming Configuration
|
||||
|
||||
The {uri-pkl-config-java-ConfigEvaluator}[`ConfigEvaluator`] class loads and evaluates Pkl modules.
|
||||
If evaluation succeeds, a {uri-pkl-config-java-Config}[`Config`] object is returned.
|
||||
Otherwise, an {uri-pkl-core-EvalException}[`EvalException`] with error details is thrown.
|
||||
|
||||
The returned `Config` object represents the root of the Pkl configuration tree.
|
||||
Intermediate and leaf nodes are also represented as `Config` objects.
|
||||
|
||||
`Config` objects offer methods to
|
||||
|
||||
* convert their Pkl value to a Java value of the specified type.
|
||||
* navigate to child nodes.
|
||||
|
||||
Let's see this in action:
|
||||
|
||||
[[config-evaluator-java-example]]
|
||||
[source,java,indent=0]
|
||||
----
|
||||
include::{examplesdir}/JavaConfigExample.java[tags=usage]
|
||||
----
|
||||
<1> Create a preconfigured `ConfigEvaluator`.
|
||||
To create a customized evaluator, start from `ConfigEvaluatorBuilder.preconfigured()` or `ConfigEvaluatorBuilder.unconfigured()`.
|
||||
The evaluator should be closed once it is no longer needed.
|
||||
In this example, this is done with a try-with-resources statement.
|
||||
Note that objects returned by the evaluator remain valid after calling `close()`.
|
||||
<2> Evaluate the given text.
|
||||
Other `evaluate` methods read from files, URLs, and other sources.
|
||||
If evaluation fails, an {uri-pkl-core-EvalException}[`EvalException`] is thrown.
|
||||
<3> Navigate from the config root to its `"pigeon"` child.
|
||||
<4> Navigate from `"pigeon"` to `"age"` and get the latter's value as an `int`.
|
||||
If conversion to the requested type fails, a `ConversionException` is thrown.
|
||||
<5> Navigate from `"pigeon"` to `"diet"` and get the latter's value as a `List<String>`.
|
||||
Note the use of `JavaType.listOf()` for creating a parameterized type literal.
|
||||
Similar methods exist for sets, maps, and other generic types.
|
||||
|
||||
A `ConfigEvaluator` caches module sources and evaluation results.
|
||||
To clear the cache, for example to evaluate the same module again, close the evaluator and create a new one.
|
||||
|
||||
For a ready-to-go example with full source code,
|
||||
see link:{uri-config-java-example}[config-java] in the _pkl/pkl-examples_ repository.
|
||||
|
||||
[[object-mapping]]
|
||||
=== Object Mapping
|
||||
|
||||
When a `Config` object needs to convert its Pkl value to a Java value, it delegates the conversion to {uri-pkl-config-java-ValueMapper}[`ValueMapper`].
|
||||
`ValueMapper` can convert an entire `PModule` or any part thereof.
|
||||
|
||||
A `ValueMapper` instance can be configured with many different Pkl-to-Java value conversions.
|
||||
`ValueMapper.preconfigured()` creates an instance configured with conversions from Pkl values to:
|
||||
|
||||
* Number types
|
||||
* Strings
|
||||
* Enums
|
||||
* Collections
|
||||
* Arrays
|
||||
* `java.util.Optional`
|
||||
* `java.time.Duration`
|
||||
* `java.net.URI/URL`
|
||||
* etc.
|
||||
|
||||
Additionally, a preconfigured `ValueMapper` instance can convert Pkl objects to Java objects with equally named properties that are settable through a constructor.
|
||||
This conversion works as follows:
|
||||
|
||||
. Find the Java class constructor with the highest number of parameters.
|
||||
. Match constructor parameters with Pkl object properties by name.
|
||||
+
|
||||
Unmatched constructor parameters result in a conversion error.
|
||||
Unmatched Pkl object properties are ignored.
|
||||
+
|
||||
. Convert each Pkl property value to the corresponding constructor parameter's type.
|
||||
. Invoke the constructor.
|
||||
|
||||
The Pkl object's runtime type is irrelevant to this conversion.
|
||||
Hence, typed and dynamic Pkl objects are equally supported.
|
||||
|
||||
To perform this conversion, `ValueMapper` needs a way to obtain the Java constructor's parameter names.
|
||||
They need to be provided in one of the following ways:
|
||||
|
||||
* Annotate constructor with `java.beans.ConstructorProperties`.
|
||||
* Annotate parameters with {uri-pkl-config-java-Named}[`Named`].
|
||||
* Annotate parameters with `javax.inject.Named`.
|
||||
* Set the Java compiler flag `-parameters`.
|
||||
|
||||
For a complete object mapping example, see:
|
||||
|
||||
* {uri-pkl-config-java-PObjectToObjectByCtorTestJava}[`PObjectToObjectByCtorTest.java`]
|
||||
|
||||
TIP: Together with xref:java-binding:codegen.adoc[code generation], object mapping provides a complete solution for consuming Pkl configuration as statically typed Java objects.
|
||||
Java code never drifts from the configuration structure defined in Pkl, and the entire configuration tree can be code-completed in Java IDEs.
|
||||
|
||||
==== Value Conversions
|
||||
|
||||
The Pkl-to-Java value conversions that ship with the library are defined in {uri-pkl-config-java-Conversions}[`Conversions`] (for individual conversions) and {uri-pkl-config-java-ConverterFactories}[`ConverterFactories`] (for families of conversions).
|
||||
To implement and register your own conversions, follow these steps:
|
||||
|
||||
. For conversions from a single source type to a single target type, implement a {uri-pkl-config-java-Conversion}[`Conversion`].
|
||||
+
|
||||
Example: `Conversions.pStringToCharacter` converts a single-character `pkl.base#String` to `java.lang.Character`.
|
||||
|
||||
. For conversions from one or multiple source types to one or multiple target types, implement a {uri-pkl-config-java-ConverterFactory}[`ConverterFactory`].
|
||||
+
|
||||
Example: `ConverterFactories.pCollectionToCollection` converts any `pkl.base#Collection` to any implementation of `java.util.Collection<E>`, for any `E`.
|
||||
+
|
||||
Converter factories are called once per combination of source type and (possibly parameterized) target type.
|
||||
The returned `Converter`s are cached.
|
||||
|
||||
. Create a `ValueMapperBuilder`, add all desired conversions, and build a `ValueMapper`.
|
||||
|
||||
. Either use the `ValueMapper` directly, or connect it to a `ConfigEvaluator` through `ConfigEvaluatorBuilder`.
|
||||
|
||||
== Further Information
|
||||
|
||||
Refer to the Javadoc and sources published with the library, or browse the library's {uri-pkl-config-java-main-sources}[main] and {uri-pkl-config-java-test-sources}[test] sources.
|
||||
23
docs/modules/java-binding/partials/cli-codegen-options.adoc
Normal file
23
docs/modules/java-binding/partials/cli-codegen-options.adoc
Normal file
@@ -0,0 +1,23 @@
|
||||
.--indent
|
||||
[%collapsible]
|
||||
====
|
||||
Default: `" "` (two spaces) +
|
||||
Example: `"\t"` (one tab) +
|
||||
The characters to use for indenting generated source code.
|
||||
====
|
||||
|
||||
.-o, --output-dir
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (not set) +
|
||||
Example: `generated/` +
|
||||
The directory where generated source code is placed.
|
||||
Relative paths are resolved against the working directory.
|
||||
====
|
||||
|
||||
.--generate-spring-boot
|
||||
[%collapsible]
|
||||
====
|
||||
Default: (not set) +
|
||||
Flag that indicates to generate config classes for use with Spring Boot.
|
||||
====
|
||||
Reference in New Issue
Block a user