Compare commits
2 Commits
master
...
record-bui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e690800a02 | ||
|
|
410cae4d32 |
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@@ -1,3 +0,0 @@
|
|||||||
# These are supported funding model platforms
|
|
||||||
|
|
||||||
github: Randgalt
|
|
||||||
24
.github/workflows/maven_java16.yml
vendored
24
.github/workflows/maven_java16.yml
vendored
@@ -1,24 +0,0 @@
|
|||||||
# This workflow will build a Java project with Maven
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
|
||||||
|
|
||||||
name: Maven Build - Java 16
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up JDK
|
|
||||||
uses: actions/setup-java@v1
|
|
||||||
with:
|
|
||||||
java-version: 16
|
|
||||||
- name: Build with Maven
|
|
||||||
run: ./mvnw -B package --file pom.xml
|
|
||||||
24
.github/workflows/maven_java17.yml
vendored
24
.github/workflows/maven_java17.yml
vendored
@@ -1,24 +0,0 @@
|
|||||||
# This workflow will build a Java project with Maven
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
|
||||||
|
|
||||||
name: Maven Build - Java 17
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Set up JDK
|
|
||||||
uses: actions/setup-java@v1
|
|
||||||
with:
|
|
||||||
java-version: 17
|
|
||||||
- name: Build with Maven
|
|
||||||
run: ./mvnw -B package --file pom.xml
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,4 +0,0 @@
|
|||||||
# Default ignored files
|
|
||||||
.idea
|
|
||||||
**/target/**
|
|
||||||
|
|
||||||
1
.mvn/jvm.config
Normal file
1
.mvn/jvm.config
Normal file
@@ -0,0 +1 @@
|
|||||||
|
--enable-preview
|
||||||
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Binary file not shown.
18
.mvn/wrapper/maven-wrapper.properties
vendored
18
.mvn/wrapper/maven-wrapper.properties
vendored
@@ -1,18 +0,0 @@
|
|||||||
# 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
|
|
||||||
#
|
|
||||||
# https://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.
|
|
||||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
|
|
||||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
|
||||||
3
.travis.yml
Normal file
3
.travis.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
language: java
|
||||||
|
jdk:
|
||||||
|
- openjdk15
|
||||||
252
README.md
252
README.md
@@ -1,13 +1,13 @@
|
|||||||
[](https://github.com/Randgalt/record-builder/actions/workflows/maven_java17.yml)
|
[](https://travis-ci.org/Randgalt/record-builder)
|
||||||
[](https://search.maven.org/search?q=g:io.soabase.record-builder%20a:record-builder)
|
[](https://search.maven.org/search?q=g:io.soabase.record-builder%20a:record-builder)
|
||||||
|
|
||||||
# RecordBuilder
|
# RecordBuilder - Early Access
|
||||||
|
|
||||||
## What is RecordBuilder
|
## What is RecordBuilder
|
||||||
|
|
||||||
Java 16 introduces [Records](https://openjdk.java.net/jeps/395). While this version of records is fantastic,
|
Java 15 introduced [Records](https://cr.openjdk.java.net/~briangoetz/amber/datum.html) as a preview feature. Since Java 9,
|
||||||
it's currently missing some important features normally found in data classes: a builder
|
features in Java are being released in stages. While the Java 15 version of records is fantastic, it's currently missing important features
|
||||||
and "with"ers. This project is an annotation processor that creates:
|
for data classes: a builder and "with"ers. This project is an annotation processor that creates:
|
||||||
|
|
||||||
- a companion builder class for Java records
|
- a companion builder class for Java records
|
||||||
- an interface that adds "with" copy methods
|
- an interface that adds "with" copy methods
|
||||||
@@ -19,9 +19,6 @@ _Details:_
|
|||||||
- [Wither Details](#Wither-Example)
|
- [Wither Details](#Wither-Example)
|
||||||
- [RecordBuilder Full Definition](#Builder-Class-Definition)
|
- [RecordBuilder Full Definition](#Builder-Class-Definition)
|
||||||
- [Record From Interface Details](#RecordInterface-Example)
|
- [Record From Interface Details](#RecordInterface-Example)
|
||||||
- [Generation Via Includes](#generation-via-includes)
|
|
||||||
- [Usage](#usage)
|
|
||||||
- [Customizing](customizing.md) (e.g. add immutable collections, etc.)
|
|
||||||
|
|
||||||
## RecordBuilder Example
|
## RecordBuilder Example
|
||||||
|
|
||||||
@@ -34,21 +31,16 @@ This will generate a builder class that can be used ala:
|
|||||||
|
|
||||||
```java
|
```java
|
||||||
// build from components
|
// build from components
|
||||||
NameAndAge n1 = NameAndAgeBuilder.builder().name(aName).age(anAge).build();
|
var n1 = NameAndAgeBuilder.builder().name(aName).age(anAge).build();
|
||||||
|
|
||||||
// generate a copy with a changed value
|
// generate a copy with a changed value
|
||||||
NameAndAge n2 = NameAndAgeBuilder.builder(n1).age(newAge).build(); // name is the same as the name in n1
|
var n2 = NameAndAgeBuilder.builder(n1).age(newAge).build(); // name is the same as the name in n1
|
||||||
|
|
||||||
// pass to other methods to set components
|
// pass to other methods to set components
|
||||||
var builder = new NameAndAgeBuilder();
|
var builder = new NameAndAgeBuilder();
|
||||||
setName(builder);
|
setName(builder);
|
||||||
setAge(builder);
|
setAge(builder);
|
||||||
NameAndAge n3 = builder.build();
|
var n3 = builder.build();
|
||||||
|
|
||||||
// use the generated static constructor/builder
|
|
||||||
import static NameAndAgeBuilder.NameAndAge;
|
|
||||||
...
|
|
||||||
var n4 = NameAndAge("hey", 42);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Wither Example
|
## Wither Example
|
||||||
@@ -61,36 +53,21 @@ public record NameAndAge(String name, int age) implements NameAndAgeBuilder.With
|
|||||||
In addition to creating a builder, your record is enhanced by "wither" methods ala:
|
In addition to creating a builder, your record is enhanced by "wither" methods ala:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
NameAndAge r1 = new NameAndAge("foo", 123);
|
var r1 = new NameAndAge("foo", 123);
|
||||||
NameAndAge r2 = r1.withName("bar");
|
var r2 = r1.withName("bar");
|
||||||
NameAndAge r3 = r2.withAge(456);
|
var r3 = r2.withAge(456);
|
||||||
|
|
||||||
// access the builder as well
|
// access the builder as well
|
||||||
NameAndAge r4 = r3.with().age(101).name("baz").build();
|
var r4 = r3.with().age(101).name("baz").build();
|
||||||
|
|
||||||
// alternate method of accessing the builder (note: no need to call "build()")
|
// alternate method of accessing the builder (note: no need to call "build()")
|
||||||
NameAndAge r5 = r4.with(b -> b.age(200).name("whatever"));
|
var r5 = r4.with(b -> b.age(200).name("whatever"));
|
||||||
|
|
||||||
// perform some logic in addition to changing values
|
|
||||||
NameAndAge r5 = r4.with(b -> {
|
|
||||||
if (b.age() > 13) {
|
|
||||||
b.name("Teen " + b.name());
|
|
||||||
} else {
|
|
||||||
b.name("whatever"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// or, if you cannot add the "With" interface to your record...
|
|
||||||
NameAndAge r6 = NameAndAgeBuilder.from(r5).with(b -> b.age(200).name("whatever"));
|
|
||||||
NameAndAge r7 = NameAndAgeBuilder.from(r5).withName("boop");
|
|
||||||
```
|
```
|
||||||
|
|
||||||
_Hat tip to [Benji Weber](https://benjiweber.co.uk/blog/2020/09/19/fun-with-java-records/) for the Withers idea._
|
_Hat tip to [Benji Weber](https://benjiweber.co.uk/blog/2020/09/19/fun-with-java-records/) for the Withers idea._
|
||||||
|
|
||||||
## Builder Class Definition
|
## Builder Class Definition
|
||||||
|
|
||||||
(Note: you can see a builder class built using `@RecordBuilderFull` here: [FullRecordBuilder.java](https://gist.github.com/Randgalt/8aa487a847ea2acdd76d702f7cf17d6a))
|
|
||||||
|
|
||||||
The full builder class is defined as:
|
The full builder class is defined as:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
@@ -107,13 +84,6 @@ public class NameAndAgeBuilder {
|
|||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Static constructor/builder. Can be used instead of new NameAndAge(...)
|
|
||||||
*/
|
|
||||||
public static NameAndAge NameAndAge(String name, int age) {
|
|
||||||
return new NameAndAge(name, age);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new builder with all fields set to default Java values
|
* Return a new builder with all fields set to default Java values
|
||||||
*/
|
*/
|
||||||
@@ -128,21 +98,6 @@ public class NameAndAgeBuilder {
|
|||||||
return new NameAndAgeBuilder(from.name(), from.age());
|
return new NameAndAgeBuilder(from.name(), from.age());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a "with"er for an existing record instance
|
|
||||||
*/
|
|
||||||
public static NameAndAgeBuilder.With from(NameAndAge from) {
|
|
||||||
return new _FromWith(from);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a stream of the record components as map entries keyed with the component name and the value as the component value
|
|
||||||
*/
|
|
||||||
public static Stream<Map.Entry<String, Object>> stream(NameAndAge record) {
|
|
||||||
return Stream.of(new AbstractMap.SimpleImmutableEntry<>("name", record.name()),
|
|
||||||
new AbstractMap.SimpleImmutableEntry<>("age", record.age()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new record instance with all fields set to the current values in this builder
|
* Return a new record instance with all fields set to the current values in this builder
|
||||||
*/
|
*/
|
||||||
@@ -150,23 +105,6 @@ public class NameAndAgeBuilder {
|
|||||||
return new NameAndAge(name, age);
|
return new NameAndAge(name, age);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NameAndAgeBuilder[name=" + name + ", age=" + age + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(name, age);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
return (this == o) || ((o instanceof NameAndAgeBuilder r)
|
|
||||||
&& Objects.equals(name, r.name)
|
|
||||||
&& (age == r.age));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a new value for the {@code name} record component in the builder
|
* Set a new value for the {@code name} record component in the builder
|
||||||
*/
|
*/
|
||||||
@@ -197,32 +135,49 @@ public class NameAndAgeBuilder {
|
|||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a stream of the record components as map entries keyed with the component name and the value as the component value
|
||||||
|
*/
|
||||||
|
public static Stream<Map.Entry<String, Object>> stream(NameAndAge record) {
|
||||||
|
return Stream.of(new AbstractMap.SimpleEntry<>("name", record.name()),
|
||||||
|
new AbstractMap.SimpleEntry<>("age", record.age()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "NameAndAgeBuilder[name=" + name + ", age=" + age + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, age);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return (this == o) || ((o instanceof NameAndAgeBuilder b)
|
||||||
|
&& Objects.equals(name, b.name)
|
||||||
|
&& (age == b.age));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add withers to {@code NameAndAge}
|
* Add withers to {@code NameAndAge}
|
||||||
*/
|
*/
|
||||||
public interface With {
|
public interface With {
|
||||||
/**
|
|
||||||
* Return the current value for the {@code name} record component in the builder
|
|
||||||
*/
|
|
||||||
String name();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the current value for the {@code age} record component in the builder
|
|
||||||
*/
|
|
||||||
int age();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new record builder using the current values
|
* Return a new record builder using the current values
|
||||||
*/
|
*/
|
||||||
default NameAndAgeBuilder with() {
|
default NameAndAgeBuilder with() {
|
||||||
return new NameAndAgeBuilder(name(), age());
|
var r = (NameAndAge)(Object)this;
|
||||||
|
return NameAndAgeBuilder.builder(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new record built from the builder passed to the given consumer
|
* Return a new record built from the builder passed to the given consumer
|
||||||
*/
|
*/
|
||||||
default NameAndAge with(Consumer<NameAndAgeBuilder> consumer) {
|
default NameAndAge with(Consumer<NameAndAgeBuilder> consumer) {
|
||||||
NameAndAgeBuilder builder = with();
|
var r = (NameAndAge)(Object)this;
|
||||||
|
NameAndAgeBuilder builder = NameAndAgeBuilder.builder(r);
|
||||||
consumer.accept(builder);
|
consumer.accept(builder);
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
@@ -231,32 +186,16 @@ public class NameAndAgeBuilder {
|
|||||||
* Return a new instance of {@code NameAndAge} with a new value for {@code name}
|
* Return a new instance of {@code NameAndAge} with a new value for {@code name}
|
||||||
*/
|
*/
|
||||||
default NameAndAge withName(String name) {
|
default NameAndAge withName(String name) {
|
||||||
return new NameAndAge(name, age());
|
var r = (NameAndAge)(Object)this;
|
||||||
|
return new NameAndAge(name, r.age());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a new instance of {@code NameAndAge} with a new value for {@code age}
|
* Return a new instance of {@code NameAndAge} with a new value for {@code age}
|
||||||
*/
|
*/
|
||||||
default NameAndAge withAge(int age) {
|
default NameAndAge withAge(int age) {
|
||||||
return new NameAndAge(name(), age);
|
var r = (NameAndAge)(Object)this;
|
||||||
}
|
return new NameAndAge(r.name(), age);
|
||||||
}
|
|
||||||
|
|
||||||
private static final class _FromWith implements NameAndAgeBuilder.With {
|
|
||||||
private final NameAndAge from;
|
|
||||||
|
|
||||||
private _FromWith(NameAndAge from) {
|
|
||||||
this.from = from;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String name() {
|
|
||||||
return from.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int age() {
|
|
||||||
return from.age();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,8 +230,6 @@ Notes:
|
|||||||
- ...cannot have type parameters
|
- ...cannot have type parameters
|
||||||
- Methods with default implementations are used in the generation unless they are annotated with `@IgnoreDefaultMethod`
|
- Methods with default implementations are used in the generation unless they are annotated with `@IgnoreDefaultMethod`
|
||||||
- If you do not want a record builder generated, annotate your interface as `@RecordInterface(addRecordBuilder = false)`
|
- If you do not want a record builder generated, annotate your interface as `@RecordInterface(addRecordBuilder = false)`
|
||||||
- If your interface is a JavaBean (e.g. `getThing()`, `isThing()`) the "get" and "is" prefixes are
|
|
||||||
stripped and forwarding methods are added.
|
|
||||||
|
|
||||||
## Generation Via Includes
|
## Generation Via Includes
|
||||||
|
|
||||||
@@ -302,7 +239,7 @@ libraries where you are not able to annotate the source.
|
|||||||
|
|
||||||
E.g.
|
E.g.
|
||||||
|
|
||||||
```java
|
```
|
||||||
import some.library.code.ImportedRecord
|
import some.library.code.ImportedRecord
|
||||||
import some.library.code.ImportedInterface
|
import some.library.code.ImportedInterface
|
||||||
|
|
||||||
@@ -316,9 +253,6 @@ public void Placeholder {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`@RecordBuilder.Include` also supports a `packages` attribute that includes all records
|
|
||||||
in the listed packages.
|
|
||||||
|
|
||||||
The target package for generation is the same as the package that contains the "Include"
|
The target package for generation is the same as the package that contains the "Include"
|
||||||
annotation. Use `packagePattern` to change this (see Javadoc for details).
|
annotation. Use `packagePattern` to change this (see Javadoc for details).
|
||||||
|
|
||||||
@@ -326,25 +260,69 @@ annotation. Use `packagePattern` to change this (see Javadoc for details).
|
|||||||
|
|
||||||
### Maven
|
### Maven
|
||||||
|
|
||||||
Add a dependency that contains the discoverable annotation processor:
|
1\. Add the dependency that contains the `@RecordBuilder` annotation.
|
||||||
|
|
||||||
```xml
|
```
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder-processor</artifactId>
|
<artifactId>record-builder-core</artifactId>
|
||||||
<version>${record.builder.version}</version>
|
<version>set-version-here</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2\. Enable the annotation processing for the Maven Compiler Plugin:
|
||||||
|
|
||||||
|
```
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>set-version-here</version>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<annotationProcessorPath>
|
||||||
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
|
<artifactId>record-builder-processor</artifactId>
|
||||||
|
<version>set-version-here</version>
|
||||||
|
</annotationProcessorPath>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
<annotationProcessors>
|
||||||
|
<annotationProcessor>io.soabase.recordbuilder.processor.RecordBuilderProcessor</annotationProcessor>
|
||||||
|
</annotationProcessors>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- "release" and "enable-preview" are required while records are preview features -->
|
||||||
|
<release>15</release>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>--enable-preview</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
|
||||||
|
... any other options here ...
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
```
|
||||||
|
|
||||||
|
3\. Enable Preview for Maven
|
||||||
|
|
||||||
|
Create a file in your project's root named `.mvn/jvm.config`. The file should have 1 line with the value: `--enable-preview`. (see: https://stackoverflow.com/questions/58023240)
|
||||||
|
|
||||||
### Gradle
|
### Gradle
|
||||||
|
|
||||||
Add the following to your build.gradle file:
|
Add the following to your build.gradle file:
|
||||||
|
|
||||||
```groovy
|
```
|
||||||
dependencies {
|
dependencies {
|
||||||
annotationProcessor 'io.soabase.record-builder:record-builder-processor:$version-goes-here'
|
annotationProcessor 'io.soabase.record-builder:record-builder-processor:$version-goes-here'
|
||||||
compileOnly 'io.soabase.record-builder:record-builder-core:$version-goes-here'
|
implementation 'io.soabase.record-builder:record-builder-core:$version-goes-here'
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.fork = true
|
||||||
|
options.forkOptions.jvmArgs += '--enable-preview'
|
||||||
|
options.compilerArgs += '--enable-preview'
|
||||||
|
}
|
||||||
|
tasks.withType(Test) {
|
||||||
|
jvmArgs += "--enable-preview"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -352,8 +330,34 @@ dependencies {
|
|||||||
|
|
||||||
Depending on your IDE you are likely to need to enable Annotation Processing in your IDE settings.
|
Depending on your IDE you are likely to need to enable Annotation Processing in your IDE settings.
|
||||||
|
|
||||||
|
## Enable Preview
|
||||||
|
|
||||||
|
Note: records are a preview feature only. You'll need take a number of steps in order to try RecordBuilder:
|
||||||
|
|
||||||
|
- Install and make active Java 15 or later
|
||||||
|
- Make sure your development tool is using Java 15 or later and is configured to enable preview features (for Maven I've documented how to do this here: [https://stackoverflow.com/a/59363152/2048051](https://stackoverflow.com/a/59363152/2048051))
|
||||||
|
- Bear in mind that this is not yet meant for production and there are numerous bugs in the tools and JDKs.
|
||||||
|
|
||||||
|
Note: I've seen some very odd compilation bugs with the current Java 15 and Maven. If you get internal Javac errors I suggest rebuilding with `mvn clean package` and/or `mvn clean install`.
|
||||||
|
|
||||||
## Customizing
|
## Customizing
|
||||||
|
|
||||||
RecordBuilder can be customized to your needs and you can even create your
|
The names of the generated methods, etc. are determined by [RecordBuilderMetaData](https://github.com/Randgalt/record-builder/blob/master/record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilderMetaData.java). If you want to use your own meta data instance:
|
||||||
own custom RecordBuilder annotations. See [Customizing RecordBuilder](customizing.md)
|
|
||||||
for details.
|
- Create a class that implements RecordBuilderMetaData
|
||||||
|
- When compiling, make sure that the compiled class is in the processor path
|
||||||
|
- Add a "metaDataClass" compiler option with the class name. E.g. `javac ... -AmetaDataClass=foo.bar.MyMetaData`
|
||||||
|
|
||||||
|
Alternatively, you can provide values for each individual meta data (or combinations):
|
||||||
|
|
||||||
|
- `javac ... -Asuffix=foo`
|
||||||
|
- `javac ... -AinterfaceSuffix=foo`
|
||||||
|
- `javac ... -AcopyMethodName=foo`
|
||||||
|
- `javac ... -AbuilderMethodName=foo`
|
||||||
|
- `javac ... -AbuildMethodName=foo`
|
||||||
|
- `javac ... -AcomponentsMethodName=foo`
|
||||||
|
- `javac ... -AwithClassName=foo`
|
||||||
|
- `javac ... -AwithClassMethodPrefix=foo`
|
||||||
|
- `javac ... -AfileComment=foo`
|
||||||
|
- `javac ... -AfileIndent=foo`
|
||||||
|
- `javac ... -AprefixEnclosingClassNames=foo`
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
[◀︎ RecordBuilder](README.md) • Customizing RecordBuilder
|
|
||||||
|
|
||||||
# RecordBuilderFull
|
|
||||||
|
|
||||||
Note: `@RecordBuilderFull` has most optional features enabled. It's an alternate
|
|
||||||
form of `@RecordBuilder` that uses the [templating mechanism](#create-a-custom-annotation) to
|
|
||||||
enable optional features.
|
|
||||||
|
|
||||||
# Customizing RecordBuilder
|
|
||||||
|
|
||||||
RecordBuilder can be customized in a number of ways. The types of customizations will change over time. See
|
|
||||||
[@RecordBuilder.Options](record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java)
|
|
||||||
for the current set of customizations and their default values. For example, the `useImmutableCollections` option
|
|
||||||
adds special handling for record components of type `java.util.List`, `java.util.Set`, `java.util.Map` and `java.util.Collection`. When the record is built, any components of these types are passed through an added shim method that uses the corresponding immutable collection (e.g. `List.copyOf(o)`) or an empty immutable collection if the component is `null`.
|
|
||||||
|
|
||||||
You can:
|
|
||||||
|
|
||||||
- [Customize an entire build](#customize-an-entire-build) - all uses of `@RecordBuilder` in your project
|
|
||||||
- [Customize a single record](#customize-a-single-record) annotated with `@RecordBuilder`
|
|
||||||
- [Create a custom annotation](#create-a-custom-annotation) that specifies your options and use that instead of `@RecordBuilder`
|
|
||||||
|
|
||||||
## Customize an entire build
|
|
||||||
|
|
||||||
To customize an entire build, use javac's annotation processor options via `-A` on the command line.
|
|
||||||
The options available are the same as the attributes in [@RecordBuilder.Options](record-builder-core/src/main/java/io/soabase/recordbuilder/core/RecordBuilder.java).
|
|
||||||
i.e. to disable "prefixing enclosing class names", compile with:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
javac -AprefixEnclosingClassNames=false ...
|
|
||||||
```
|
|
||||||
|
|
||||||
_Note: use a separate `-A` for each option._
|
|
||||||
|
|
||||||
#### Maven
|
|
||||||
|
|
||||||
If you are using Maven, specify the options in the compiler plugin:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>${maven-compiler-plugin-version}</version>
|
|
||||||
<configuration>
|
|
||||||
<compilerArgs>
|
|
||||||
<arg>-AprefixEnclosingClassNames=false</arg>
|
|
||||||
<arg>-AfileComment="something different"</arg>
|
|
||||||
</compilerArgs>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Gradle
|
|
||||||
|
|
||||||
For Gradle, specify the options:
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
compilerArgs.addAll(['-AprefixEnclosingClassNames=false', '-AfileComment="something different"'])
|
|
||||||
```
|
|
||||||
|
|
||||||
## Customize a single record
|
|
||||||
|
|
||||||
To customize a single record, add `@RecordBuilder.Options` in addition to
|
|
||||||
`@RecordBuilder`.
|
|
||||||
|
|
||||||
E.g.
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RecordBuilder.Options(withClassName = "Wither")
|
|
||||||
@RecordBuilder
|
|
||||||
public record MyRecord(String s){}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Create a custom annotation
|
|
||||||
|
|
||||||
Using `@RecordBuilder.Template` you can create your own RecordBuilder annotation
|
|
||||||
that uses the set of options you want. E.g. to create a custom annotation that
|
|
||||||
uses an alternate file comment and an alternate With classname:
|
|
||||||
|
|
||||||
```java
|
|
||||||
@RecordBuilder.Template(options = @RecordBuilder.Options(
|
|
||||||
fileComment = "MyCo license",
|
|
||||||
withClassName = "Wither"
|
|
||||||
))
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Inherited
|
|
||||||
public @interface MyCoRecordBuilder {
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Now, you can use `@MyCoRecordBuilder` instead of `@RecordBuilder` and the record
|
|
||||||
will be built with options as specified.
|
|
||||||
|
|
||||||
Note: the template mechanism also supports `@RecordInterface` templates via the `asRecordInterface` attribute.
|
|
||||||
When it is set a `@RecordInterface` template is created instead.
|
|
||||||
287
mvnw
vendored
287
mvnw
vendored
@@ -1,287 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
# 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 Wrapper startup batch script, version 3.1.1
|
|
||||||
#
|
|
||||||
# Required ENV vars:
|
|
||||||
# ------------------
|
|
||||||
# JAVA_HOME - location of a JDK home dir
|
|
||||||
#
|
|
||||||
# Optional ENV vars
|
|
||||||
# -----------------
|
|
||||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
|
||||||
# e.g. to debug Maven itself, use
|
|
||||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
|
||||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
|
||||||
# ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
|
||||||
|
|
||||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
|
||||||
. /usr/local/etc/mavenrc
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f /etc/mavenrc ] ; then
|
|
||||||
. /etc/mavenrc
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$HOME/.mavenrc" ] ; then
|
|
||||||
. "$HOME/.mavenrc"
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# OS specific support. $var _must_ be set to either true or false.
|
|
||||||
cygwin=false;
|
|
||||||
darwin=false;
|
|
||||||
mingw=false
|
|
||||||
case "`uname`" in
|
|
||||||
CYGWIN*) cygwin=true ;;
|
|
||||||
MINGW*) mingw=true;;
|
|
||||||
Darwin*) darwin=true
|
|
||||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
|
||||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
|
||||||
if [ -z "$JAVA_HOME" ]; then
|
|
||||||
if [ -x "/usr/libexec/java_home" ]; then
|
|
||||||
JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
|
|
||||||
else
|
|
||||||
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -z "$JAVA_HOME" ] ; then
|
|
||||||
if [ -r /etc/gentoo-release ] ; then
|
|
||||||
JAVA_HOME=`java-config --jre-home`
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
|
||||||
if $cygwin ; then
|
|
||||||
[ -n "$JAVA_HOME" ] &&
|
|
||||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
|
||||||
[ -n "$CLASSPATH" ] &&
|
|
||||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
|
||||||
if $mingw ; then
|
|
||||||
[ -n "$JAVA_HOME" ] &&
|
|
||||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$JAVA_HOME" ]; then
|
|
||||||
javaExecutable="`which javac`"
|
|
||||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
|
||||||
# readlink(1) is not available as standard on Solaris 10.
|
|
||||||
readLink=`which readlink`
|
|
||||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
|
||||||
if $darwin ; then
|
|
||||||
javaHome="`dirname \"$javaExecutable\"`"
|
|
||||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
|
||||||
else
|
|
||||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
|
||||||
fi
|
|
||||||
javaHome="`dirname \"$javaExecutable\"`"
|
|
||||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
|
||||||
JAVA_HOME="$javaHome"
|
|
||||||
export JAVA_HOME
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$JAVACMD" ] ; then
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
||||||
else
|
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD="`\\unset -f command; \\command -v java`"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
|
||||||
echo " We cannot execute $JAVACMD" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$JAVA_HOME" ] ; then
|
|
||||||
echo "Warning: JAVA_HOME environment variable is not set."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# traverses directory structure from process work directory to filesystem root
|
|
||||||
# first directory with .mvn subdirectory is considered project base directory
|
|
||||||
find_maven_basedir() {
|
|
||||||
if [ -z "$1" ]
|
|
||||||
then
|
|
||||||
echo "Path not specified to find_maven_basedir"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
basedir="$1"
|
|
||||||
wdir="$1"
|
|
||||||
while [ "$wdir" != '/' ] ; do
|
|
||||||
if [ -d "$wdir"/.mvn ] ; then
|
|
||||||
basedir=$wdir
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
|
||||||
if [ -d "${wdir}" ]; then
|
|
||||||
wdir=`cd "$wdir/.."; pwd`
|
|
||||||
fi
|
|
||||||
# end of workaround
|
|
||||||
done
|
|
||||||
printf '%s' "$(cd "$basedir"; pwd)"
|
|
||||||
}
|
|
||||||
|
|
||||||
# concatenates all lines of a file
|
|
||||||
concat_lines() {
|
|
||||||
if [ -f "$1" ]; then
|
|
||||||
echo "$(tr -s '\n' ' ' < "$1")"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
BASE_DIR=$(find_maven_basedir "$(dirname $0)")
|
|
||||||
if [ -z "$BASE_DIR" ]; then
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo $MAVEN_PROJECTBASEDIR
|
|
||||||
fi
|
|
||||||
|
|
||||||
##########################################################################################
|
|
||||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
|
||||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
|
||||||
##########################################################################################
|
|
||||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
|
||||||
fi
|
|
||||||
if [ -n "$MVNW_REPOURL" ]; then
|
|
||||||
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
|
||||||
else
|
|
||||||
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
|
||||||
fi
|
|
||||||
while IFS="=" read key value; do
|
|
||||||
case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
|
|
||||||
esac
|
|
||||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo "Downloading from: $wrapperUrl"
|
|
||||||
fi
|
|
||||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
|
||||||
if $cygwin; then
|
|
||||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
|
||||||
fi
|
|
||||||
|
|
||||||
if command -v wget > /dev/null; then
|
|
||||||
QUIET="--quiet"
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo "Found wget ... using wget"
|
|
||||||
QUIET=""
|
|
||||||
fi
|
|
||||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
|
||||||
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
|
|
||||||
else
|
|
||||||
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
|
|
||||||
fi
|
|
||||||
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
|
|
||||||
elif command -v curl > /dev/null; then
|
|
||||||
QUIET="--silent"
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo "Found curl ... using curl"
|
|
||||||
QUIET=""
|
|
||||||
fi
|
|
||||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
|
||||||
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
|
|
||||||
else
|
|
||||||
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
|
|
||||||
fi
|
|
||||||
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
|
|
||||||
else
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo "Falling back to using Java to download"
|
|
||||||
fi
|
|
||||||
javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
|
||||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
|
|
||||||
# For Cygwin, switch paths to Windows format before running javac
|
|
||||||
if $cygwin; then
|
|
||||||
javaSource=`cygpath --path --windows "$javaSource"`
|
|
||||||
javaClass=`cygpath --path --windows "$javaClass"`
|
|
||||||
fi
|
|
||||||
if [ -e "$javaSource" ]; then
|
|
||||||
if [ ! -e "$javaClass" ]; then
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
|
||||||
fi
|
|
||||||
# Compiling the Java class
|
|
||||||
("$JAVA_HOME/bin/javac" "$javaSource")
|
|
||||||
fi
|
|
||||||
if [ -e "$javaClass" ]; then
|
|
||||||
# Running the downloader
|
|
||||||
if [ "$MVNW_VERBOSE" = true ]; then
|
|
||||||
echo " - Running MavenWrapperDownloader.java ..."
|
|
||||||
fi
|
|
||||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
##########################################################################################
|
|
||||||
# End of extension
|
|
||||||
##########################################################################################
|
|
||||||
|
|
||||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
|
||||||
|
|
||||||
# For Cygwin, switch paths to Windows format before running java
|
|
||||||
if $cygwin; then
|
|
||||||
[ -n "$JAVA_HOME" ] &&
|
|
||||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
|
||||||
[ -n "$CLASSPATH" ] &&
|
|
||||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
|
||||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
|
||||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Provide a "standardized" way to retrieve the CLI args that will
|
|
||||||
# work with both Windows and non-Windows executions.
|
|
||||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
|
||||||
export MAVEN_CMD_LINE_ARGS
|
|
||||||
|
|
||||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
|
||||||
|
|
||||||
exec "$JAVACMD" \
|
|
||||||
$MAVEN_OPTS \
|
|
||||||
$MAVEN_DEBUG_OPTS \
|
|
||||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
|
||||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
|
||||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
|
||||||
187
mvnw.cmd
vendored
187
mvnw.cmd
vendored
@@ -1,187 +0,0 @@
|
|||||||
@REM ----------------------------------------------------------------------------
|
|
||||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
@REM or more contributor license agreements. See the NOTICE file
|
|
||||||
@REM distributed with this work for additional information
|
|
||||||
@REM regarding copyright ownership. The ASF licenses this file
|
|
||||||
@REM to you under the Apache License, Version 2.0 (the
|
|
||||||
@REM "License"); you may not use this file except in compliance
|
|
||||||
@REM with the License. You may obtain a copy of the License at
|
|
||||||
@REM
|
|
||||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
@REM
|
|
||||||
@REM Unless required by applicable law or agreed to in writing,
|
|
||||||
@REM software distributed under the License is distributed on an
|
|
||||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
@REM KIND, either express or implied. See the License for the
|
|
||||||
@REM specific language governing permissions and limitations
|
|
||||||
@REM under the License.
|
|
||||||
@REM ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@REM ----------------------------------------------------------------------------
|
|
||||||
@REM Apache Maven Wrapper startup batch script, version 3.1.1
|
|
||||||
@REM
|
|
||||||
@REM Required ENV vars:
|
|
||||||
@REM JAVA_HOME - location of a JDK home dir
|
|
||||||
@REM
|
|
||||||
@REM Optional ENV vars
|
|
||||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
|
||||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
|
||||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
|
||||||
@REM e.g. to debug Maven itself, use
|
|
||||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
|
||||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
|
||||||
@REM ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
|
||||||
@echo off
|
|
||||||
@REM set title of command window
|
|
||||||
title %0
|
|
||||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
|
||||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
|
||||||
|
|
||||||
@REM set %HOME% to equivalent of $HOME
|
|
||||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
|
||||||
|
|
||||||
@REM Execute a user defined script before this one
|
|
||||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
|
||||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
|
||||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
|
||||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
|
||||||
:skipRcPre
|
|
||||||
|
|
||||||
@setlocal
|
|
||||||
|
|
||||||
set ERROR_CODE=0
|
|
||||||
|
|
||||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
|
||||||
@setlocal
|
|
||||||
|
|
||||||
@REM ==== START VALIDATION ====
|
|
||||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Error: JAVA_HOME not found in your environment. >&2
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
|
||||||
echo location of your Java installation. >&2
|
|
||||||
echo.
|
|
||||||
goto error
|
|
||||||
|
|
||||||
:OkJHome
|
|
||||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
|
||||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
|
||||||
echo location of your Java installation. >&2
|
|
||||||
echo.
|
|
||||||
goto error
|
|
||||||
|
|
||||||
@REM ==== END VALIDATION ====
|
|
||||||
|
|
||||||
:init
|
|
||||||
|
|
||||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
|
||||||
@REM Fallback to current working directory if not found.
|
|
||||||
|
|
||||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
|
||||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
|
||||||
|
|
||||||
set EXEC_DIR=%CD%
|
|
||||||
set WDIR=%EXEC_DIR%
|
|
||||||
:findBaseDir
|
|
||||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
|
||||||
cd ..
|
|
||||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
|
||||||
set WDIR=%CD%
|
|
||||||
goto findBaseDir
|
|
||||||
|
|
||||||
:baseDirFound
|
|
||||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
|
||||||
cd "%EXEC_DIR%"
|
|
||||||
goto endDetectBaseDir
|
|
||||||
|
|
||||||
:baseDirNotFound
|
|
||||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
|
||||||
cd "%EXEC_DIR%"
|
|
||||||
|
|
||||||
:endDetectBaseDir
|
|
||||||
|
|
||||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
|
||||||
|
|
||||||
@setlocal EnableExtensions EnableDelayedExpansion
|
|
||||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
|
||||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
|
||||||
|
|
||||||
:endReadAdditionalConfig
|
|
||||||
|
|
||||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
|
||||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
|
||||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
|
||||||
|
|
||||||
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
|
||||||
|
|
||||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
|
||||||
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
|
|
||||||
)
|
|
||||||
|
|
||||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
|
||||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
|
||||||
if exist %WRAPPER_JAR% (
|
|
||||||
if "%MVNW_VERBOSE%" == "true" (
|
|
||||||
echo Found %WRAPPER_JAR%
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
if not "%MVNW_REPOURL%" == "" (
|
|
||||||
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
|
||||||
)
|
|
||||||
if "%MVNW_VERBOSE%" == "true" (
|
|
||||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
|
||||||
echo Downloading from: %WRAPPER_URL%
|
|
||||||
)
|
|
||||||
|
|
||||||
powershell -Command "&{"^
|
|
||||||
"$webclient = new-object System.Net.WebClient;"^
|
|
||||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
|
||||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
|
||||||
"}"^
|
|
||||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
|
|
||||||
"}"
|
|
||||||
if "%MVNW_VERBOSE%" == "true" (
|
|
||||||
echo Finished downloading %WRAPPER_JAR%
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@REM End of extension
|
|
||||||
|
|
||||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
|
||||||
@REM work with both Windows and non-Windows executions.
|
|
||||||
set MAVEN_CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
%MAVEN_JAVA_EXE% ^
|
|
||||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
|
||||||
%MAVEN_OPTS% ^
|
|
||||||
%MAVEN_DEBUG_OPTS% ^
|
|
||||||
-classpath %WRAPPER_JAR% ^
|
|
||||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
|
||||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
|
||||||
if ERRORLEVEL 1 goto error
|
|
||||||
goto end
|
|
||||||
|
|
||||||
:error
|
|
||||||
set ERROR_CODE=1
|
|
||||||
|
|
||||||
:end
|
|
||||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
|
||||||
|
|
||||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
|
||||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
|
||||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
|
||||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
|
||||||
:skipRcPost
|
|
||||||
|
|
||||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
|
||||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
|
||||||
|
|
||||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
|
||||||
|
|
||||||
cmd /C exit /B %ERROR_CODE%
|
|
||||||
143
pom.xml
143
pom.xml
@@ -1,34 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright 2019 The original author or authors
|
|
||||||
|
|
||||||
Licensed 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.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder</artifactId>
|
<artifactId>record-builder</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>38-SNAPSHOT</version>
|
<version>1.11.ea</version>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>record-builder-core</module>
|
<module>record-builder-core</module>
|
||||||
<module>record-builder-processor</module>
|
<module>record-builder-processor</module>
|
||||||
<module>record-builder-test</module>
|
<module>record-builder-test</module>
|
||||||
<module>record-builder-validator</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -36,33 +18,23 @@
|
|||||||
<project.build.resourceEncoding>UTF-8</project.build.resourceEncoding>
|
<project.build.resourceEncoding>UTF-8</project.build.resourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
<jdk-version>16</jdk-version>
|
<jdk-version>15</jdk-version>
|
||||||
|
|
||||||
<maven-compiler-plugin-version>3.8.1</maven-compiler-plugin-version>
|
<maven-compiler-plugin-version>3.8.1</maven-compiler-plugin-version>
|
||||||
<maven-source-plugin-version>3.2.0</maven-source-plugin-version>
|
<maven-source-plugin-version>3.2.0</maven-source-plugin-version>
|
||||||
<maven-install-plugin-version>2.5.2</maven-install-plugin-version>
|
<maven-install-plugin-version>2.5.2</maven-install-plugin-version>
|
||||||
<maven-deploy-plugin-version>2.8.2</maven-deploy-plugin-version>
|
<maven-deploy-plugin-version>2.8.2</maven-deploy-plugin-version>
|
||||||
<maven-license-plugin-version>4.1</maven-license-plugin-version>
|
<maven-license-plugin-version>1.9.0</maven-license-plugin-version>
|
||||||
<maven-gpg-plugin-version>1.6</maven-gpg-plugin-version>
|
<maven-gpg-plugin-version>1.6</maven-gpg-plugin-version>
|
||||||
<maven-javadoc-plugin-version>3.1.1</maven-javadoc-plugin-version>
|
<maven-javadoc-plugin-version>3.1.1</maven-javadoc-plugin-version>
|
||||||
<maven-clean-plugin-version>3.1.0</maven-clean-plugin-version>
|
<maven-clean-plugin-version>3.1.0</maven-clean-plugin-version>
|
||||||
<maven-shade-plugin-version>3.2.1</maven-shade-plugin-version>
|
<maven-shade-plugin-version>3.2.1</maven-shade-plugin-version>
|
||||||
<maven-release-plugin-version>2.5.3</maven-release-plugin-version>
|
<maven-release-plugin-version>2.5.3</maven-release-plugin-version>
|
||||||
<maven-jar-plugin-version>3.2.0</maven-jar-plugin-version>
|
|
||||||
<maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
|
<maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
|
||||||
|
|
||||||
<jacoco-maven-plugin-version>0.8.7</jacoco-maven-plugin-version>
|
|
||||||
<formatter-maven-plugin-version>2.22.0</formatter-maven-plugin-version>
|
|
||||||
|
|
||||||
<license-file-path>src/etc/header.txt</license-file-path>
|
|
||||||
|
|
||||||
<javapoet-version>1.12.1</javapoet-version>
|
<javapoet-version>1.12.1</javapoet-version>
|
||||||
<junit-jupiter-version>5.5.2</junit-jupiter-version>
|
<junit-jupiter-version>5.5.2</junit-jupiter-version>
|
||||||
<assertj-core.version>3.24.2</assertj-core.version>
|
|
||||||
<asm-version>7.2</asm-version>
|
<asm-version>7.2</asm-version>
|
||||||
<validation-api-version>2.0.1.Final</validation-api-version>
|
|
||||||
<hibernate-validator-version>6.0.20.Final</hibernate-validator-version>
|
|
||||||
<javax-el-version>3.0.1-b09</javax-el-version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<name>Record Builder</name>
|
<name>Record Builder</name>
|
||||||
@@ -99,7 +71,7 @@
|
|||||||
<url>https://github.com/randgalt/record-builder</url>
|
<url>https://github.com/randgalt/record-builder</url>
|
||||||
<connection>scm:git:https://github.com/randgalt/record-builder.git</connection>
|
<connection>scm:git:https://github.com/randgalt/record-builder.git</connection>
|
||||||
<developerConnection>scm:git:git@github.com:randgalt/record-builder.git</developerConnection>
|
<developerConnection>scm:git:git@github.com:randgalt/record-builder.git</developerConnection>
|
||||||
<tag>record-builder-1.16</tag>
|
<tag>record-builder-1.11.ea</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<issueManagement>
|
<issueManagement>
|
||||||
@@ -134,65 +106,26 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
|
||||||
<artifactId>record-builder-processor</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
|
||||||
<artifactId>record-builder-validator</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<version>${junit-jupiter-version}</version>
|
<version>${junit-jupiter-version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>${assertj-core.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>javax.validation</groupId>
|
|
||||||
<artifactId>validation-api</artifactId>
|
|
||||||
<version>${validation-api-version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate.validator</groupId>
|
|
||||||
<artifactId>hibernate-validator</artifactId>
|
|
||||||
<version>${hibernate-validator-version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish</groupId>
|
|
||||||
<artifactId>javax.el</artifactId>
|
|
||||||
<version>${javax-el-version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<pluginManagement>
|
<pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>${maven-surefire-plugin-version}</version>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>${maven-compiler-plugin-version}</version>
|
<version>${maven-compiler-plugin-version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<release>${jdk-version}</release>
|
<release>${jdk-version}</release>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>--enable-preview</arg>
|
||||||
|
</compilerArgs>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
@@ -220,11 +153,11 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mycila</groupId>
|
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
<artifactId>maven-license-plugin</artifactId>
|
||||||
<version>${maven-license-plugin-version}</version>
|
<version>${maven-license-plugin-version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<header>${license-file-path}</header>
|
<header>src/etc/header.txt</header>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*.apt</exclude>
|
<exclude>**/*.apt</exclude>
|
||||||
<exclude>**/*.md</exclude>
|
<exclude>**/*.md</exclude>
|
||||||
@@ -250,10 +183,6 @@
|
|||||||
<exclude>**/jvm.config</exclude>
|
<exclude>**/jvm.config</exclude>
|
||||||
<exclude>**/.java-version</exclude>
|
<exclude>**/.java-version</exclude>
|
||||||
<exclude>**/.travis.yml</exclude>
|
<exclude>**/.travis.yml</exclude>
|
||||||
<exclude>**/gradlew</exclude>
|
|
||||||
<exclude>**/.github/**</exclude>
|
|
||||||
<exclude>**/.mvn/**</exclude>
|
|
||||||
<exclude>**/mvnw*</exclude>
|
|
||||||
</excludes>
|
</excludes>
|
||||||
<strictCheck>true</strictCheck>
|
<strictCheck>true</strictCheck>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -346,38 +275,11 @@
|
|||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>${maven-jar-plugin-version}</version>
|
<version>${maven-surefire-plugin-version}</version>
|
||||||
</plugin>
|
<configuration>
|
||||||
|
<argLine>--enable-preview</argLine>
|
||||||
<plugin>
|
</configuration>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
|
||||||
<version>${maven-gpg-plugin-version}</version>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<version>${jacoco-maven-plugin-version}</version>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>net.revelc.code.formatter</groupId>
|
|
||||||
<artifactId>formatter-maven-plugin</artifactId>
|
|
||||||
<version>${formatter-maven-plugin-version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>validate</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>format</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<compilerCompliance>17</compilerCompliance>
|
|
||||||
<compilerSource>17</compilerSource>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
@@ -399,8 +301,8 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.mycila</groupId>
|
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
<artifactId>maven-license-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -412,16 +314,6 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-release-plugin</artifactId>
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>net.revelc.code.formatter</groupId>
|
|
||||||
<artifactId>formatter-maven-plugin</artifactId>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
@@ -432,6 +324,7 @@
|
|||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>${maven-gpg-plugin-version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<passphrase>${gpg.passphrase}</passphrase>
|
<passphrase>${gpg.passphrase}</passphrase>
|
||||||
<useAgent>true</useAgent>
|
<useAgent>true</useAgent>
|
||||||
|
|||||||
@@ -1,48 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright 2019 The original author or authors
|
|
||||||
|
|
||||||
Licensed 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.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder</artifactId>
|
<artifactId>record-builder</artifactId>
|
||||||
<version>38-SNAPSHOT</version>
|
<version>1.11.ea</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>record-builder-core</artifactId>
|
<artifactId>record-builder-core</artifactId>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<license-file-path>${project.parent.basedir}/src/etc/header.txt</license-file-path>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestEntries>
|
|
||||||
<Automatic-Module-Name>io.soabase.recordbuilder.core</Automatic-Module-Name>
|
|
||||||
</manifestEntries>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,294 +16,26 @@
|
|||||||
package io.soabase.recordbuilder.core;
|
package io.soabase.recordbuilder.core;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Inherited;
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import javax.lang.model.element.Modifier;
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Inherited
|
|
||||||
public @interface RecordBuilder {
|
public @interface RecordBuilder {
|
||||||
@Target({ ElementType.TYPE, ElementType.PACKAGE })
|
@Target({ElementType.TYPE, ElementType.PACKAGE})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Inherited
|
|
||||||
@interface Include {
|
@interface Include {
|
||||||
/**
|
Class<?>[] value();
|
||||||
* @return collection of classes to include
|
|
||||||
*/
|
|
||||||
Class<?>[] value() default {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synonym for {@code value()}. When using the other attributes it maybe clearer to use {@code classes()}
|
* Pattern used to generate the package for the generated class. The value
|
||||||
* instead of {@code value()}. Note: both attributes are applied (i.e. a union of classes from both attributes).
|
* is the literal package name however two replacement values can be used. '@'
|
||||||
*
|
* is replaced with the package of the Include annotation. '*' is replaced with
|
||||||
* @return collection of classes
|
* the package of the included class.
|
||||||
*/
|
|
||||||
Class<?>[] classes() default {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional list of package names. All records in the packages will get processed as if they were listed as
|
|
||||||
* classes to include.
|
|
||||||
*
|
|
||||||
* @return collection of package names
|
|
||||||
*/
|
|
||||||
String[] packages() default {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pattern used to generate the package for the generated class. The value is the literal package name however
|
|
||||||
* two replacement values can be used. '@' is replaced with the package of the {@code Include} annotation. '*'
|
|
||||||
* is replaced with the package of the included class.
|
|
||||||
*
|
*
|
||||||
* @return package pattern
|
* @return package pattern
|
||||||
*/
|
*/
|
||||||
String packagePattern() default "@";
|
String packagePattern() default "@";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
@Target({ ElementType.TYPE, ElementType.PACKAGE })
|
|
||||||
@Inherited
|
|
||||||
@interface Options {
|
|
||||||
/**
|
|
||||||
* The builder class name will be the name of the record (prefixed with any enclosing class) plus this suffix.
|
|
||||||
* E.g. if the record name is "Foo", the builder will be named "FooBuilder".
|
|
||||||
*/
|
|
||||||
String suffix() default "Builder";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by {@code RecordInterface}. The generated record will have the same name as the annotated interface plus
|
|
||||||
* this suffix. E.g. if the interface name is "Foo", the record will be named "FooRecord".
|
|
||||||
*/
|
|
||||||
String interfaceSuffix() default "Record";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name to use for the copy builder
|
|
||||||
*/
|
|
||||||
String copyMethodName() default "builder";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name to use for the builder
|
|
||||||
*/
|
|
||||||
String builderMethodName() default "builder";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name to use for the build method
|
|
||||||
*/
|
|
||||||
String buildMethodName() default "build";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name to use for the from-to-wither method
|
|
||||||
*/
|
|
||||||
String fromMethodName() default "from";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name to use for the method that returns the record components as a stream
|
|
||||||
*/
|
|
||||||
String componentsMethodName() default "stream";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, a "With" interface is generated and an associated static factory
|
|
||||||
*/
|
|
||||||
boolean enableWither() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name to use for the nested With class
|
|
||||||
*/
|
|
||||||
String withClassName() default "With";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The prefix to use for the methods in the With class
|
|
||||||
*/
|
|
||||||
String withClassMethodPrefix() default "with";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the comment to place at the top of generated files. Return null or an empty string for no comment.
|
|
||||||
*/
|
|
||||||
String fileComment() default "Auto generated by io.soabase.recordbuilder.core.RecordBuilder: https://github.com/Randgalt/record-builder";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the file indent to use
|
|
||||||
*/
|
|
||||||
String fileIndent() default " ";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the record is declared inside another class, the outer class's name will be prefixed to the builder name
|
|
||||||
* if this returns true.
|
|
||||||
*/
|
|
||||||
boolean prefixEnclosingClassNames() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, any annotations (if applicable) on record components are copied to the builder methods
|
|
||||||
*
|
|
||||||
* @return true/false
|
|
||||||
*/
|
|
||||||
boolean inheritComponentAnnotations() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the default value of {@code Optional} record components to {@code Optional.empty()}
|
|
||||||
*/
|
|
||||||
boolean emptyDefaultForOptional() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add non-optional setter methods for optional record components.
|
|
||||||
*/
|
|
||||||
boolean addConcreteSettersForOptional() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add not-null checks for record components annotated with any annotation named either "NotNull", "NoNull", or
|
|
||||||
* "NonNull" (see {@link #interpretNotNullsPattern()} for the actual regex matching pattern).
|
|
||||||
*/
|
|
||||||
boolean interpretNotNulls() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #interpretNotNulls()} is true, this is the regex pattern used to determine if an annotation name
|
|
||||||
* means "not null"
|
|
||||||
*/
|
|
||||||
String interpretNotNullsPattern() default "(?i)((notnull)|(nonnull)|(nonull))";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* Pass built records through the Java Validation API if it's available in the classpath.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* IMPORTANT: if this option is enabled you must include the {@code record-builder-validator} dependency in
|
|
||||||
* addition to {@code record-builder-core}. {@code record-builder-validator} is implemented completely via
|
|
||||||
* reflection and does not require other dependencies. Alternatively, you can define your own class with the
|
|
||||||
* package {@code package io.soabase.recordbuilder.validator;} named {@code RecordBuilderValidator} which has a
|
|
||||||
* public static method: {@code public static <T> T validate(T o)}.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
boolean useValidationApi() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds special handling for record components of type {@link java.util.List}, {@link java.util.Set},
|
|
||||||
* {@link java.util.Map} and {@link java.util.Collection}. When the record is built, any components of these
|
|
||||||
* types are passed through an added shim method that uses the corresponding immutable collection (e.g.
|
|
||||||
* {@code List.copyOf(o)}) or an empty immutable collection if the component is {@code null}.
|
|
||||||
*
|
|
||||||
* @see #useUnmodifiableCollections()
|
|
||||||
*/
|
|
||||||
boolean useImmutableCollections() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds special handling for record components of type: {@link java.util.List}, {@link java.util.Set},
|
|
||||||
* {@link java.util.Map} and {@link java.util.Collection}. When the record is built, any components of these
|
|
||||||
* types are passed through an added shim method that uses the corresponding unmodifiable collection (e.g.
|
|
||||||
* {@code Collections.unmodifiableList(o)}) or an empty immutable collection if the component is {@code null}.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* For backward compatibility, when {@link #useImmutableCollections()} returns {@code true}, this property is
|
|
||||||
* ignored.
|
|
||||||
*
|
|
||||||
* @see #useImmutableCollections()
|
|
||||||
*
|
|
||||||
* @since 37
|
|
||||||
*/
|
|
||||||
boolean useUnmodifiableCollections() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When enabled, collection types ({@code List}, {@code Set} and {@code Map}) are handled specially. The setters
|
|
||||||
* for these types now create an internal collection and items are added to that collection. Additionally,
|
|
||||||
* "adder" methods prefixed with {@link #singleItemBuilderPrefix()} are created to add single items to these
|
|
||||||
* collections.
|
|
||||||
*/
|
|
||||||
boolean addSingleItemCollectionBuilders() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The prefix for adder methods when {@link #addSingleItemCollectionBuilders()} is enabled
|
|
||||||
*/
|
|
||||||
String singleItemBuilderPrefix() default "add";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When enabled, adds functional methods to the nested "With" class (such as {@code map()} and
|
|
||||||
* {@code accept()}).
|
|
||||||
*/
|
|
||||||
boolean addFunctionalMethodsToWith() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, all builder setter methods will be prefixed with this string. Camel-casing will still be enforced, so
|
|
||||||
* if this option is set to "set" a field named "myField" will get a corresponding setter named "setMyField".
|
|
||||||
*/
|
|
||||||
String setterPrefix() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, getters will be generated for the Builder class.
|
|
||||||
*/
|
|
||||||
boolean enableGetters() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, all builder getter methods will be prefixed with this string. Camel-casing will still be enforced, so
|
|
||||||
* if this option is set to "get", a field named "myField" will get a corresponding getter named "getMyField".
|
|
||||||
*/
|
|
||||||
String getterPrefix() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, all boolean builder getter methods will be prefixed with this string. Camel-casing will still be
|
|
||||||
* enforced, so if this option is set to "is", a field named "myField" will get a corresponding getter named
|
|
||||||
* "isMyField".
|
|
||||||
*/
|
|
||||||
String booleanPrefix() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, the Builder will contain an internal interface with this name. This interface contains getters for
|
|
||||||
* all the fields in the Record prefixed with the value supplied in {@link this.getterPrefix} and
|
|
||||||
* {@link this.booleanPrefix}. This interface can be implemented by the original Record to have proper
|
|
||||||
* bean-style prefixed getters. Please note that unless either of the aforementioned prefixes are set, this
|
|
||||||
* option does nothing.
|
|
||||||
*/
|
|
||||||
String beanClassName() default "";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, generated classes are annotated with {@code RecordBuilderGenerated} which has a retention policy of
|
|
||||||
* {@code CLASS}. This ensures that analyzers such as Jacoco will ignore the generated class.
|
|
||||||
*/
|
|
||||||
boolean addClassRetainedGenerated() default false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link #fromMethodName} method instantiates an internal private class. This is the name of that class.
|
|
||||||
*/
|
|
||||||
String fromWithClassName() default "_FromWith";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true, a functional-style builder is added so that record instances can be instantiated without
|
|
||||||
* {@code new}.
|
|
||||||
*/
|
|
||||||
boolean addStaticBuilder() default true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #addSingleItemCollectionBuilders()} and {@link #useImmutableCollections()} are enabled the builder
|
|
||||||
* uses an internal class to track changes to lists. This is the name of that class.
|
|
||||||
*/
|
|
||||||
String mutableListClassName() default "_MutableList";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #addSingleItemCollectionBuilders()} and {@link #useImmutableCollections()} are enabled the builder
|
|
||||||
* uses an internal class to track changes to sets. This is the name of that class.
|
|
||||||
*/
|
|
||||||
String mutableSetClassName() default "_MutableSet";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If {@link #addSingleItemCollectionBuilders()} and {@link #useImmutableCollections()} are enabled the builder
|
|
||||||
* uses an internal class to track changes to maps. This is the name of that class.
|
|
||||||
*/
|
|
||||||
String mutableMapClassName() default "_MutableMap";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Any additional {@link javax.lang.model.element.Modifier} you wish to apply to the builder. For example to
|
|
||||||
* make the builder public when the record is package protect.
|
|
||||||
*/
|
|
||||||
Modifier[] builderClassModifiers() default {};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Retention(RetentionPolicy.CLASS)
|
|
||||||
@Target(ElementType.ANNOTATION_TYPE)
|
|
||||||
@Inherited
|
|
||||||
@interface Template {
|
|
||||||
RecordBuilder.Options options();
|
|
||||||
|
|
||||||
boolean asRecordInterface() default false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.core;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An alternate form of {@code @RecordBuilder} that has most optional features turned on
|
|
||||||
*/
|
|
||||||
@RecordBuilder.Template(options = @RecordBuilder.Options(interpretNotNulls = true, useImmutableCollections = true, addSingleItemCollectionBuilders = true, addFunctionalMethodsToWith = true, addClassRetainedGenerated = true))
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Inherited
|
|
||||||
public @interface RecordBuilderFull {
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.core;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
import static java.lang.annotation.ElementType.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Jacoco ignores classes and methods annotated with `*Generated`
|
|
||||||
*/
|
|
||||||
@Target({ PACKAGE, TYPE, METHOD, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, PARAMETER })
|
|
||||||
@Retention(RetentionPolicy.CLASS)
|
|
||||||
public @interface RecordBuilderGenerated {
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2019 Jordan Zimmerman
|
||||||
|
*
|
||||||
|
* Licensed 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 io.soabase.recordbuilder.core;
|
||||||
|
|
||||||
|
public interface RecordBuilderMetaData {
|
||||||
|
/**
|
||||||
|
* If you want to use your own meta data instance:
|
||||||
|
* <ul>
|
||||||
|
* <li>create a class that implements {@code RecordBuilderMetaData}</li>
|
||||||
|
* <li>When compiling, make sure that compiled class is in the processor path</li>
|
||||||
|
* <li>Add a "metaDataClass" compiler option with the class name. E.g. {@code javac ... -AmetaDataClass=foo.bar.MyMetaData}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
String JAVAC_OPTION_NAME = "metaDataClass";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default meta data instance
|
||||||
|
*/
|
||||||
|
RecordBuilderMetaData DEFAULT = new RecordBuilderMetaData() {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builder class name will be the name of the record (prefixed with any enclosing class) plus this suffix. E.g.
|
||||||
|
* if the record name is "Foo", the builder will be named "FooBuilder".
|
||||||
|
*
|
||||||
|
* @return suffix
|
||||||
|
*/
|
||||||
|
default String suffix() {
|
||||||
|
return "Builder";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by {@code RecordInterface}. The generated record will have the same name as the annotated interface
|
||||||
|
* plus this suffix. E.g. if the interface name is "Foo", the record will be named "FooRecord".
|
||||||
|
*
|
||||||
|
* @return suffix
|
||||||
|
*/
|
||||||
|
default String interfaceSuffix() {
|
||||||
|
return "Record";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name to use for the copy builder
|
||||||
|
*
|
||||||
|
* @return copy builder name
|
||||||
|
*/
|
||||||
|
default String copyMethodName() {
|
||||||
|
return builderMethodName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name to use for the builder
|
||||||
|
*
|
||||||
|
* @return builder name
|
||||||
|
*/
|
||||||
|
default String builderMethodName() {
|
||||||
|
return "builder";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name to use for the build method
|
||||||
|
*
|
||||||
|
* @return build method
|
||||||
|
*/
|
||||||
|
default String buildMethodName() {
|
||||||
|
return "build";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name to use for the method that returns the record components as a stream
|
||||||
|
*
|
||||||
|
* @return build method
|
||||||
|
*/
|
||||||
|
default String componentsMethodName() {
|
||||||
|
return "stream";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name to use for the nested With class
|
||||||
|
*
|
||||||
|
* @return with class name
|
||||||
|
*/
|
||||||
|
default String withClassName() {
|
||||||
|
return "With";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix to use for the methods in the With class
|
||||||
|
*
|
||||||
|
* @return prefix
|
||||||
|
*/
|
||||||
|
default String withClassMethodPrefix() {
|
||||||
|
return "with";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the comment to place at the top of generated files. Return null or an empty string for no comment.
|
||||||
|
*
|
||||||
|
* @return comment or empty
|
||||||
|
*/
|
||||||
|
default String fileComment() {
|
||||||
|
return "Auto generated by io.soabase.recordbuilder.core.RecordBuilder: https://github.com/Randgalt/record-builder";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the file indent to use
|
||||||
|
*
|
||||||
|
* @return file index
|
||||||
|
*/
|
||||||
|
default String fileIndent() {
|
||||||
|
return " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the record is declared inside of another class, the outer class's name will
|
||||||
|
* be prefixed to the builder name if this returns true.
|
||||||
|
*
|
||||||
|
* @return true/false
|
||||||
|
*/
|
||||||
|
default boolean prefixEnclosingClassNames() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,42 +15,28 @@
|
|||||||
*/
|
*/
|
||||||
package io.soabase.recordbuilder.core;
|
package io.soabase.recordbuilder.core;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Inherited
|
|
||||||
public @interface RecordInterface {
|
public @interface RecordInterface {
|
||||||
boolean addRecordBuilder() default true;
|
boolean addRecordBuilder() default true;
|
||||||
|
|
||||||
@Target({ ElementType.TYPE, ElementType.PACKAGE })
|
@Target({ElementType.TYPE, ElementType.PACKAGE})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Inherited
|
|
||||||
@interface Include {
|
@interface Include {
|
||||||
/**
|
Class<?>[] value();
|
||||||
* @return collection of classes to include
|
|
||||||
*/
|
|
||||||
Class<?>[] value() default {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Synonym for {@code value()}. When using the other attributes it maybe clearer to use {@code classes()}
|
|
||||||
* instead of {@code value()}. Note: both attributes are applied (i.e. a union of classes from both attributes).
|
|
||||||
*
|
|
||||||
* @return collection of classes
|
|
||||||
*/
|
|
||||||
Class<?>[] classes() default {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If true the generated record is annotated with {@code @RecordBuilder}
|
|
||||||
*
|
|
||||||
* @return true/false
|
|
||||||
*/
|
|
||||||
boolean addRecordBuilder() default true;
|
boolean addRecordBuilder() default true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pattern used to generate the package for the generated class. The value is the literal package name however
|
* Pattern used to generate the package for the generated class. The value
|
||||||
* two replacement values can be used. '@' is replaced with the package of the {@code Include} annotation. '*'
|
* is the literal package name however two replacement values can be used. '@'
|
||||||
* is replaced with the package of the included class.
|
* is replaced with the package of the Include annotation. '*' is replaced with
|
||||||
|
* the package of the included class.
|
||||||
*
|
*
|
||||||
* @return package pattern
|
* @return package pattern
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,35 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright 2019 The original author or authors
|
|
||||||
|
|
||||||
Licensed 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.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder</artifactId>
|
<artifactId>record-builder</artifactId>
|
||||||
<version>38-SNAPSHOT</version>
|
<version>1.11.ea</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>record-builder-processor</artifactId>
|
<artifactId>record-builder-processor</artifactId>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<license-file-path>${project.parent.basedir}/src/etc/header.txt</license-file-path>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup</groupId>
|
<groupId>com.squareup</groupId>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,396 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.processor;
|
|
||||||
|
|
||||||
import com.squareup.javapoet.*;
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.lang.model.element.Modifier;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordBuilderAnnotation;
|
|
||||||
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation;
|
|
||||||
|
|
||||||
class CollectionBuilderUtils {
|
|
||||||
private final boolean useImmutableCollections;
|
|
||||||
private final boolean useUnmodifiableCollections;
|
|
||||||
private final boolean addSingleItemCollectionBuilders;
|
|
||||||
private final boolean addClassRetainedGenerated;
|
|
||||||
private final String listShimName;
|
|
||||||
private final String mapShimName;
|
|
||||||
private final String setShimName;
|
|
||||||
private final String collectionShimName;
|
|
||||||
|
|
||||||
private final String listMakerMethodName;
|
|
||||||
private final String mapMakerMethodName;
|
|
||||||
private final String setMakerMethodName;
|
|
||||||
|
|
||||||
private boolean needsListShim;
|
|
||||||
private boolean needsMapShim;
|
|
||||||
private boolean needsSetShim;
|
|
||||||
private boolean needsCollectionShim;
|
|
||||||
|
|
||||||
private boolean needsListMutableMaker;
|
|
||||||
private boolean needsMapMutableMaker;
|
|
||||||
private boolean needsSetMutableMaker;
|
|
||||||
|
|
||||||
private static final Class<?> listType = List.class;
|
|
||||||
private static final Class<?> mapType = Map.class;
|
|
||||||
private static final Class<?> setType = Set.class;
|
|
||||||
private static final Class<?> collectionType = Collection.class;
|
|
||||||
private static final Class<?> collectionsType = Collections.class;
|
|
||||||
private static final TypeName listTypeName = TypeName.get(listType);
|
|
||||||
private static final TypeName mapTypeName = TypeName.get(mapType);
|
|
||||||
private static final TypeName setTypeName = TypeName.get(setType);
|
|
||||||
private static final TypeName collectionTypeName = TypeName.get(collectionType);
|
|
||||||
private static final TypeName collectionsTypeName = TypeName.get(collectionsType);
|
|
||||||
|
|
||||||
private static final TypeVariableName tType = TypeVariableName.get("T");
|
|
||||||
private static final TypeVariableName kType = TypeVariableName.get("K");
|
|
||||||
private static final TypeVariableName vType = TypeVariableName.get("V");
|
|
||||||
private static final ParameterizedTypeName parameterizedListType = ParameterizedTypeName
|
|
||||||
.get(ClassName.get(List.class), tType);
|
|
||||||
private static final ParameterizedTypeName parameterizedMapType = ParameterizedTypeName
|
|
||||||
.get(ClassName.get(Map.class), kType, vType);
|
|
||||||
private static final ParameterizedTypeName parameterizedSetType = ParameterizedTypeName
|
|
||||||
.get(ClassName.get(Set.class), tType);
|
|
||||||
private static final ParameterizedTypeName parameterizedCollectionType = ParameterizedTypeName
|
|
||||||
.get(ClassName.get(Collection.class), tType);
|
|
||||||
|
|
||||||
private static final Class<?> mutableListType = ArrayList.class;
|
|
||||||
private static final Class<?> mutableMapType = HashMap.class;
|
|
||||||
private static final Class<?> mutableSetType = HashSet.class;
|
|
||||||
private static final ClassName mutableListTypeName = ClassName.get(mutableListType);
|
|
||||||
private static final ClassName mutableMapTypeName = ClassName.get(mutableMapType);
|
|
||||||
private static final ClassName mutableSetTypeName = ClassName.get(mutableSetType);
|
|
||||||
private final TypeSpec mutableListSpec;
|
|
||||||
private final TypeSpec mutableSetSpec;
|
|
||||||
private final TypeSpec mutableMapSpec;
|
|
||||||
|
|
||||||
CollectionBuilderUtils(List<RecordClassType> recordComponents, RecordBuilder.Options metaData) {
|
|
||||||
useImmutableCollections = metaData.useImmutableCollections();
|
|
||||||
useUnmodifiableCollections = !useImmutableCollections && metaData.useUnmodifiableCollections();
|
|
||||||
addSingleItemCollectionBuilders = metaData.addSingleItemCollectionBuilders();
|
|
||||||
addClassRetainedGenerated = metaData.addClassRetainedGenerated();
|
|
||||||
|
|
||||||
listShimName = disambiguateGeneratedMethodName(recordComponents, "__list", 0);
|
|
||||||
mapShimName = disambiguateGeneratedMethodName(recordComponents, "__map", 0);
|
|
||||||
setShimName = disambiguateGeneratedMethodName(recordComponents, "__set", 0);
|
|
||||||
collectionShimName = disambiguateGeneratedMethodName(recordComponents, "__collection", 0);
|
|
||||||
|
|
||||||
listMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureListMutable", 0);
|
|
||||||
setMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureSetMutable", 0);
|
|
||||||
mapMakerMethodName = disambiguateGeneratedMethodName(recordComponents, "__ensureMapMutable", 0);
|
|
||||||
|
|
||||||
mutableListSpec = buildMutableCollectionSubType(metaData.mutableListClassName(), mutableListTypeName,
|
|
||||||
parameterizedListType, tType);
|
|
||||||
mutableSetSpec = buildMutableCollectionSubType(metaData.mutableSetClassName(), mutableSetTypeName,
|
|
||||||
parameterizedSetType, tType);
|
|
||||||
mutableMapSpec = buildMutableCollectionSubType(metaData.mutableMapClassName(), mutableMapTypeName,
|
|
||||||
parameterizedMapType, kType, vType);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SingleItemsMetaDataMode {
|
|
||||||
STANDARD, STANDARD_FOR_SETTER, EXCLUDE_WILDCARD_TYPES
|
|
||||||
}
|
|
||||||
|
|
||||||
record SingleItemsMetaData(Class<?> singleItemCollectionClass, List<TypeName> typeArguments, TypeName wildType) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Optional<SingleItemsMetaData> singleItemsMetaData(RecordClassType component, SingleItemsMetaDataMode mode) {
|
|
||||||
if (addSingleItemCollectionBuilders
|
|
||||||
&& (component.typeName() instanceof ParameterizedTypeName parameterizedTypeName)) {
|
|
||||||
Class<?> collectionClass = null;
|
|
||||||
ClassName wildcardClass = null;
|
|
||||||
int typeArgumentQty = 0;
|
|
||||||
if (isList(component)) {
|
|
||||||
collectionClass = mutableListType;
|
|
||||||
wildcardClass = ClassName.get(Collection.class);
|
|
||||||
typeArgumentQty = 1;
|
|
||||||
} else if (isSet(component)) {
|
|
||||||
collectionClass = mutableSetType;
|
|
||||||
wildcardClass = ClassName.get(Collection.class);
|
|
||||||
typeArgumentQty = 1;
|
|
||||||
} else if (isMap(component)) {
|
|
||||||
collectionClass = mutableMapType;
|
|
||||||
wildcardClass = (ClassName) component.rawTypeName();
|
|
||||||
typeArgumentQty = 2;
|
|
||||||
}
|
|
||||||
var hasWildcardTypeArguments = hasWildcardTypeArguments(parameterizedTypeName, typeArgumentQty);
|
|
||||||
if (collectionClass != null) {
|
|
||||||
return switch (mode) {
|
|
||||||
case STANDARD -> singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass,
|
|
||||||
typeArgumentQty);
|
|
||||||
|
|
||||||
case STANDARD_FOR_SETTER -> {
|
|
||||||
if (hasWildcardTypeArguments) {
|
|
||||||
yield Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments,
|
|
||||||
component.typeName()));
|
|
||||||
}
|
|
||||||
yield singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass,
|
|
||||||
typeArgumentQty);
|
|
||||||
}
|
|
||||||
|
|
||||||
case EXCLUDE_WILDCARD_TYPES -> {
|
|
||||||
if (hasWildcardTypeArguments) {
|
|
||||||
yield Optional.empty();
|
|
||||||
}
|
|
||||||
yield singleItemsMetaDataWithWildType(parameterizedTypeName, collectionClass, wildcardClass,
|
|
||||||
typeArgumentQty);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isImmutableCollection(RecordClassType component) {
|
|
||||||
return (useImmutableCollections || useUnmodifiableCollections)
|
|
||||||
&& (isList(component) || isMap(component) || isSet(component) || isCollection(component));
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isList(RecordClassType component) {
|
|
||||||
return component.rawTypeName().equals(listTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isMap(RecordClassType component) {
|
|
||||||
return component.rawTypeName().equals(mapTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isSet(RecordClassType component) {
|
|
||||||
return component.rawTypeName().equals(setTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isCollection(RecordClassType component) {
|
|
||||||
return component.rawTypeName().equals(collectionTypeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addShimCall(CodeBlock.Builder builder, RecordClassType component) {
|
|
||||||
if (useImmutableCollections || useUnmodifiableCollections) {
|
|
||||||
if (isList(component)) {
|
|
||||||
needsListShim = true;
|
|
||||||
needsListMutableMaker = true;
|
|
||||||
builder.add("$L($L)", listShimName, component.name());
|
|
||||||
} else if (isMap(component)) {
|
|
||||||
needsMapShim = true;
|
|
||||||
needsMapMutableMaker = true;
|
|
||||||
builder.add("$L($L)", mapShimName, component.name());
|
|
||||||
} else if (isSet(component)) {
|
|
||||||
needsSetShim = true;
|
|
||||||
needsSetMutableMaker = true;
|
|
||||||
builder.add("$L($L)", setShimName, component.name());
|
|
||||||
} else if (isCollection(component)) {
|
|
||||||
needsCollectionShim = true;
|
|
||||||
builder.add("$L($L)", collectionShimName, component.name());
|
|
||||||
} else {
|
|
||||||
builder.add("$L", component.name());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
builder.add("$L", component.name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String shimName(RecordClassType component) {
|
|
||||||
if (isList(component)) {
|
|
||||||
return listShimName;
|
|
||||||
} else if (isMap(component)) {
|
|
||||||
return mapShimName;
|
|
||||||
} else if (isSet(component)) {
|
|
||||||
return setShimName;
|
|
||||||
} else if (isCollection(component)) {
|
|
||||||
return collectionShimName;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(component + " is not a supported collection type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String mutableMakerName(RecordClassType component) {
|
|
||||||
if (isList(component)) {
|
|
||||||
return listMakerMethodName;
|
|
||||||
} else if (isMap(component)) {
|
|
||||||
return mapMakerMethodName;
|
|
||||||
} else if (isSet(component)) {
|
|
||||||
return setMakerMethodName;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(component + " is not a supported collection type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addShims(TypeSpec.Builder builder) {
|
|
||||||
if (!useImmutableCollections && !useUnmodifiableCollections) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsListShim) {
|
|
||||||
builder.addMethod(
|
|
||||||
buildShimMethod(listShimName, listTypeName, collectionType, parameterizedListType, tType));
|
|
||||||
}
|
|
||||||
if (needsSetShim) {
|
|
||||||
builder.addMethod(buildShimMethod(setShimName, setTypeName, collectionType, parameterizedSetType, tType));
|
|
||||||
}
|
|
||||||
if (needsMapShim) {
|
|
||||||
builder.addMethod(buildShimMethod(mapShimName, mapTypeName, mapType, parameterizedMapType, kType, vType));
|
|
||||||
}
|
|
||||||
if (needsCollectionShim) {
|
|
||||||
builder.addMethod(buildCollectionsShimMethod());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addMutableMakers(TypeSpec.Builder builder) {
|
|
||||||
if (!useImmutableCollections && !useUnmodifiableCollections) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsListMutableMaker) {
|
|
||||||
builder.addMethod(
|
|
||||||
buildMutableMakerMethod(listMakerMethodName, mutableListSpec.name, parameterizedListType, tType));
|
|
||||||
builder.addType(mutableListSpec);
|
|
||||||
}
|
|
||||||
if (needsSetMutableMaker) {
|
|
||||||
builder.addMethod(
|
|
||||||
buildMutableMakerMethod(setMakerMethodName, mutableSetSpec.name, parameterizedSetType, tType));
|
|
||||||
builder.addType(mutableSetSpec);
|
|
||||||
}
|
|
||||||
if (needsMapMutableMaker) {
|
|
||||||
builder.addMethod(buildMutableMakerMethod(mapMakerMethodName, mutableMapSpec.name, parameterizedMapType,
|
|
||||||
kType, vType));
|
|
||||||
builder.addType(mutableMapSpec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<SingleItemsMetaData> singleItemsMetaDataWithWildType(ParameterizedTypeName parameterizedTypeName,
|
|
||||||
Class<?> collectionClass, ClassName wildcardClass, int typeArgumentQty) {
|
|
||||||
TypeName wildType;
|
|
||||||
if (typeArgumentQty == 1) {
|
|
||||||
wildType = ParameterizedTypeName.get(wildcardClass,
|
|
||||||
WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(0)));
|
|
||||||
} else { // if (typeArgumentQty == 2)
|
|
||||||
wildType = ParameterizedTypeName.get(wildcardClass,
|
|
||||||
WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(0)),
|
|
||||||
WildcardTypeName.subtypeOf(parameterizedTypeName.typeArguments.get(1)));
|
|
||||||
}
|
|
||||||
return Optional.of(new SingleItemsMetaData(collectionClass, parameterizedTypeName.typeArguments, wildType));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasWildcardTypeArguments(ParameterizedTypeName parameterizedTypeName, int argumentCount) {
|
|
||||||
for (int i = 0; i < argumentCount; ++i) {
|
|
||||||
if (parameterizedTypeName.typeArguments.size() > i) {
|
|
||||||
if (parameterizedTypeName.typeArguments.get(i) instanceof WildcardTypeName) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String disambiguateGeneratedMethodName(List<RecordClassType> recordComponents, String baseName, int index) {
|
|
||||||
var name = (index == 0) ? baseName : (baseName + index);
|
|
||||||
if (recordComponents.stream().anyMatch(component -> component.name().equals(name))) {
|
|
||||||
return disambiguateGeneratedMethodName(recordComponents, baseName, index + 1);
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodSpec buildShimMethod(String name, TypeName mainType, Class<?> abstractType,
|
|
||||||
ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
|
|
||||||
var code = buildShimMethodBody(mainType, parameterizedType);
|
|
||||||
|
|
||||||
TypeName[] wildCardTypeArguments = parameterizedType.typeArguments.stream().map(WildcardTypeName::subtypeOf)
|
|
||||||
.toList().toArray(new TypeName[0]);
|
|
||||||
var extendedParameterizedType = ParameterizedTypeName.get(ClassName.get(abstractType), wildCardTypeArguments);
|
|
||||||
return MethodSpec.methodBuilder(name).addAnnotation(generatedRecordBuilderAnnotation)
|
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC).addTypeVariables(Arrays.asList(typeVariables))
|
|
||||||
.returns(parameterizedType).addParameter(extendedParameterizedType, "o").addStatement(code).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CodeBlock buildShimMethodBody(TypeName mainType, ParameterizedTypeName parameterizedType) {
|
|
||||||
if (!useUnmodifiableCollections) {
|
|
||||||
return CodeBlock.of("return (o != null) ? $T.copyOf(o) : $T.of()", mainType, mainType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainType.equals(listTypeName)) {
|
|
||||||
return CodeBlock.of("return (o != null) ? $T.<$T>unmodifiableList(($T) o) : $T.<$T>emptyList()",
|
|
||||||
collectionsTypeName, tType, parameterizedType, collectionsTypeName, tType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainType.equals(setTypeName)) {
|
|
||||||
return CodeBlock.of("return (o != null) ? $T.<$T>unmodifiableSet(($T) o) : $T.<$T>emptySet()",
|
|
||||||
collectionsTypeName, tType, parameterizedType, collectionsTypeName, tType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mainType.equals(mapTypeName)) {
|
|
||||||
return CodeBlock.of("return (o != null) ? $T.<$T, $T>unmodifiableMap(($T) o) : $T.<$T, $T>emptyMap()",
|
|
||||||
collectionsTypeName, kType, vType, parameterizedType, collectionsTypeName, kType, vType);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException("Cannot build shim method for" + mainType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodSpec buildMutableMakerMethod(String name, String mutableCollectionType,
|
|
||||||
ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
|
|
||||||
var nullCase = CodeBlock.of("if (o == null) return new $L<>()", mutableCollectionType);
|
|
||||||
var isMutableCase = CodeBlock.of("if (o instanceof $L) return o", mutableCollectionType);
|
|
||||||
var defaultCase = CodeBlock.of("return new $L<>(o)", mutableCollectionType);
|
|
||||||
return MethodSpec.methodBuilder(name).addAnnotation(generatedRecordBuilderAnnotation)
|
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC).addTypeVariables(Arrays.asList(typeVariables))
|
|
||||||
.returns(parameterizedType).addParameter(parameterizedType, "o").addStatement(nullCase)
|
|
||||||
.addStatement(isMutableCase).addStatement(defaultCase).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeSpec buildMutableCollectionSubType(String className, ClassName mutableCollectionType,
|
|
||||||
ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
|
|
||||||
TypeName[] typeArguments = new TypeName[] {};
|
|
||||||
typeArguments = Arrays.stream(typeVariables).toList().toArray(typeArguments);
|
|
||||||
|
|
||||||
TypeSpec.Builder builder = TypeSpec.classBuilder(className).addAnnotation(generatedRecordBuilderAnnotation)
|
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
|
|
||||||
.superclass(ParameterizedTypeName.get(mutableCollectionType, typeArguments))
|
|
||||||
.addTypeVariables(Arrays.asList(typeVariables))
|
|
||||||
.addMethod(MethodSpec.constructorBuilder().addAnnotation(generatedRecordBuilderAnnotation)
|
|
||||||
.addStatement("super()").build())
|
|
||||||
.addMethod(MethodSpec.constructorBuilder().addAnnotation(generatedRecordBuilderAnnotation)
|
|
||||||
.addParameter(parameterizedType, "o").addStatement("super(o)").build());
|
|
||||||
|
|
||||||
if (addClassRetainedGenerated) {
|
|
||||||
builder.addAnnotation(recordBuilderGeneratedAnnotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodSpec buildCollectionsShimMethod() {
|
|
||||||
var code = buildCollectionShimMethodBody();
|
|
||||||
return MethodSpec.methodBuilder(collectionShimName).addAnnotation(generatedRecordBuilderAnnotation)
|
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC).addTypeVariable(tType)
|
|
||||||
.returns(parameterizedCollectionType).addParameter(parameterizedCollectionType, "o").addCode(code)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CodeBlock buildCollectionShimMethodBody() {
|
|
||||||
if (!useUnmodifiableCollections) {
|
|
||||||
return CodeBlock.builder().add("if (o instanceof Set) {\n").indent()
|
|
||||||
.addStatement("return $T.copyOf(o)", setTypeName).unindent().addStatement("}")
|
|
||||||
.addStatement("return (o != null) ? $T.copyOf(o) : $T.of()", listTypeName, listTypeName).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
return CodeBlock.builder().beginControlFlow("if (o instanceof $T)", listType)
|
|
||||||
.addStatement("return $T.<$T>unmodifiableList(($T) o)", collectionsTypeName, tType,
|
|
||||||
parameterizedListType)
|
|
||||||
.endControlFlow().beginControlFlow("if (o instanceof $T)", setType)
|
|
||||||
.addStatement("return $T.<$T>unmodifiableSet(($T) o)", collectionsTypeName, tType, parameterizedSetType)
|
|
||||||
.endControlFlow().addStatement("return $T.<$T>emptyList()", collectionsTypeName, tType).build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,12 +19,11 @@ import com.squareup.javapoet.ClassName;
|
|||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeVariableName;
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
import io.soabase.recordbuilder.core.RecordBuilderMetaData;
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.AnnotationValue;
|
import javax.lang.model.element.AnnotationValue;
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
import javax.lang.model.element.ElementKind;
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.RecordComponentElement;
|
import javax.lang.model.element.RecordComponentElement;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
@@ -37,43 +36,42 @@ import java.util.Optional;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ElementUtils {
|
public class ElementUtils {
|
||||||
public static Optional<? extends AnnotationMirror> findAnnotationMirror(ProcessingEnvironment processingEnv,
|
public static Optional<? extends AnnotationMirror> findAnnotationMirror(ProcessingEnvironment processingEnv, Element element, String annotationClass) {
|
||||||
Element element, String annotationClass) {
|
|
||||||
return processingEnv.getElementUtils().getAllAnnotationMirrors(element).stream()
|
return processingEnv.getElementUtils().getAllAnnotationMirrors(element).stream()
|
||||||
.filter(e -> e.getAnnotationType().toString().equals(annotationClass)).findFirst();
|
.filter(e -> e.getAnnotationType().toString().equals(annotationClass))
|
||||||
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<? extends AnnotationValue> getAnnotationValue(
|
public static Optional<? extends AnnotationValue> getAnnotationValue(Map<? extends ExecutableElement, ? extends AnnotationValue> values, String name) {
|
||||||
Map<? extends ExecutableElement, ? extends AnnotationValue> values, String name) {
|
return values.entrySet()
|
||||||
return values.entrySet().stream().filter(e -> e.getKey().getSimpleName().toString().equals(name))
|
.stream()
|
||||||
.map(Map.Entry::getValue).findFirst();
|
.filter(e -> e.getKey().getSimpleName().toString().equals(name))
|
||||||
|
.map(Map.Entry::getValue)
|
||||||
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static List<TypeMirror> getAttributeTypeMirrorList(AnnotationValue attribute) {
|
public static List<TypeMirror> getClassesAttribute(AnnotationValue attribute)
|
||||||
List<? extends AnnotationValue> values = (attribute != null)
|
{
|
||||||
? (List<? extends AnnotationValue>) attribute.getValue() : Collections.emptyList();
|
List<? extends AnnotationValue> values = (attribute != null) ? (List<? extends AnnotationValue>)attribute.getValue() : Collections.emptyList();
|
||||||
return values.stream().map(v -> (TypeMirror) v.getValue()).collect(Collectors.toList());
|
return values.stream().map(v -> (TypeMirror)v.getValue()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public static boolean getBooleanAttribute(AnnotationValue attribute)
|
||||||
public static List<String> getAttributeStringList(AnnotationValue attribute) {
|
{
|
||||||
List<? extends AnnotationValue> values = (attribute != null)
|
|
||||||
? (List<? extends AnnotationValue>) attribute.getValue() : Collections.emptyList();
|
|
||||||
return values.stream().map(v -> (String) v.getValue()).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getBooleanAttribute(AnnotationValue attribute) {
|
|
||||||
Object value = (attribute != null) ? attribute.getValue() : null;
|
Object value = (attribute != null) ? attribute.getValue() : null;
|
||||||
if (value != null) {
|
if ( value != null )
|
||||||
|
{
|
||||||
return Boolean.parseBoolean(String.valueOf(value));
|
return Boolean.parseBoolean(String.valueOf(value));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getStringAttribute(AnnotationValue attribute, String defaultValue) {
|
public static String getStringAttribute(AnnotationValue attribute, String defaultValue)
|
||||||
|
{
|
||||||
Object value = (attribute != null) ? attribute.getValue() : null;
|
Object value = (attribute != null) ? attribute.getValue() : null;
|
||||||
if (value != null) {
|
if ( value != null )
|
||||||
|
{
|
||||||
return String.valueOf(value);
|
return String.valueOf(value);
|
||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
@@ -88,13 +86,11 @@ public class ElementUtils {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String name = typeElement.getQualifiedName().toString();
|
String name = typeElement.getEnclosingElement().toString();
|
||||||
int index = name.lastIndexOf(".");
|
return !name.equals("unnamed package") ? name : "";
|
||||||
return (index > -1) ? name.substring(0, index) : "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClassType getClassType(String packageName, String simpleName,
|
public static ClassType getClassType(String packageName, String simpleName, List<? extends TypeParameterElement> typeParameters) {
|
||||||
List<? extends TypeParameterElement> typeParameters) {
|
|
||||||
return getClassType(ClassName.get(packageName, simpleName), typeParameters);
|
return getClassType(ClassName.get(packageName, simpleName), typeParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,8 +98,7 @@ public class ElementUtils {
|
|||||||
return getClassType(ClassName.get(typeElement), typeParameters);
|
return getClassType(ClassName.get(typeElement), typeParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClassType getClassType(ClassName builderClassName,
|
public static ClassType getClassType(ClassName builderClassName, List<? extends TypeParameterElement> typeParameters) {
|
||||||
List<? extends TypeParameterElement> typeParameters) {
|
|
||||||
if (typeParameters.isEmpty()) {
|
if (typeParameters.isEmpty()) {
|
||||||
return new ClassType(builderClassName, builderClassName.simpleName());
|
return new ClassType(builderClassName, builderClassName.simpleName());
|
||||||
}
|
}
|
||||||
@@ -111,13 +106,8 @@ public class ElementUtils {
|
|||||||
return new ClassType(ParameterizedTypeName.get(builderClassName, typeNames), builderClassName.simpleName());
|
return new ClassType(ParameterizedTypeName.get(builderClassName, typeNames), builderClassName.simpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecordClassType getRecordClassType(ProcessingEnvironment processingEnv,
|
public static ClassType getClassType(RecordComponentElement recordComponent) {
|
||||||
RecordComponentElement recordComponent, List<? extends AnnotationMirror> accessorAnnotations,
|
return new ClassType(TypeName.get(recordComponent.asType()), recordComponent.getSimpleName().toString());
|
||||||
List<? extends AnnotationMirror> canonicalConstructorAnnotations) {
|
|
||||||
var typeName = TypeName.get(recordComponent.asType());
|
|
||||||
var rawTypeName = TypeName.get(processingEnv.getTypeUtils().erasure(recordComponent.asType()));
|
|
||||||
return new RecordClassType(typeName, rawTypeName, recordComponent.getSimpleName().toString(),
|
|
||||||
accessorAnnotations, canonicalConstructorAnnotations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getWithMethodName(ClassType component, String prefix) {
|
public static String getWithMethodName(ClassType component, String prefix) {
|
||||||
@@ -128,30 +118,10 @@ public class ElementUtils {
|
|||||||
return prefix + Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
return prefix + Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBuilderName(TypeElement element, RecordBuilder.Options metaData, ClassType classType,
|
public static String getBuilderName(TypeElement element, RecordBuilderMetaData metaData, ClassType classType, String suffix) {
|
||||||
String suffix) {
|
|
||||||
// generate the class name
|
// generate the class name
|
||||||
var baseName = classType.name() + suffix;
|
var baseName = classType.name() + suffix;
|
||||||
return metaData.prefixEnclosingClassNames() ? (getBuilderNamePrefix(element.getEnclosingElement()) + baseName)
|
return metaData.prefixEnclosingClassNames() ? (getBuilderNamePrefix(element.getEnclosingElement()) + baseName) : baseName;
|
||||||
: baseName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<? extends Element> findCanonicalConstructor(TypeElement record) {
|
|
||||||
if (record.getKind() != ElementKind.RECORD) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// based on
|
|
||||||
// https://github.com/openjdk/jdk/pull/3556/files#diff-a6270f4b50989abe733607c69038b2036306d13f77276af005d023b7fc57f1a2R2368
|
|
||||||
var componentList = record.getRecordComponents().stream().map(e -> e.asType().toString())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
return record.getEnclosedElements().stream().filter(element -> element.getKind() == ElementKind.CONSTRUCTOR)
|
|
||||||
.filter(element -> {
|
|
||||||
var parameters = ((ExecutableElement) element).getParameters();
|
|
||||||
var parametersList = parameters.stream().map(e -> e.asType().toString())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
return componentList.equals(parametersList);
|
|
||||||
}).findFirst();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getBuilderNamePrefix(Element element) {
|
private static String getBuilderNamePrefix(Element element) {
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.processor;
|
|
||||||
|
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
|
||||||
import javax.lang.model.element.*;
|
|
||||||
import javax.lang.model.type.TypeMirror;
|
|
||||||
import javax.tools.Diagnostic;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class IncludeHelper {
|
|
||||||
private final boolean isValid;
|
|
||||||
private final List<TypeElement> classTypeElements;
|
|
||||||
private final Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValues;
|
|
||||||
|
|
||||||
IncludeHelper(ProcessingEnvironment processingEnv, Element element, AnnotationMirror annotationMirror,
|
|
||||||
boolean packagesSupported) {
|
|
||||||
annotationValues = processingEnv.getElementUtils().getElementValuesWithDefaults(annotationMirror);
|
|
||||||
var value = ElementUtils.getAnnotationValue(annotationValues, "value");
|
|
||||||
var classes = ElementUtils.getAnnotationValue(annotationValues, "classes");
|
|
||||||
var packages = ElementUtils.getAnnotationValue(annotationValues, "packages");
|
|
||||||
var isValid = true;
|
|
||||||
var classTypeElements = new ArrayList<TypeElement>();
|
|
||||||
if (value.isPresent() || classes.isPresent() || packages.isPresent()) {
|
|
||||||
var valueList = value.map(ElementUtils::getAttributeTypeMirrorList).orElseGet(List::of);
|
|
||||||
var classesList = classes.map(ElementUtils::getAttributeTypeMirrorList).orElseGet(List::of);
|
|
||||||
var packagesList = packages.map(ElementUtils::getAttributeStringList).orElseGet(List::of);
|
|
||||||
if (valueList.isEmpty() && classesList.isEmpty() && packagesList.isEmpty()) {
|
|
||||||
if (packagesSupported) {
|
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
|
||||||
"At least one of \"value\", \"classes\" or \"packages\" required", element);
|
|
||||||
} else {
|
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
|
||||||
"At least one of \"value\" or \"classes\" required", element);
|
|
||||||
}
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
isValid = processList(processingEnv, isValid, element, valueList, classTypeElements);
|
|
||||||
isValid = processList(processingEnv, isValid, element, classesList, classTypeElements);
|
|
||||||
packages.ifPresent(annotationValue -> processPackages(processingEnv, classTypeElements, packagesList));
|
|
||||||
} else {
|
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not read attribute for annotation",
|
|
||||||
element);
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
this.isValid = isValid;
|
|
||||||
this.classTypeElements = List.copyOf(classTypeElements);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<? extends ExecutableElement, ? extends AnnotationValue> getAnnotationValues() {
|
|
||||||
return annotationValues;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isValid() {
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<TypeElement> getClassTypeElements() {
|
|
||||||
return classTypeElements;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean processList(ProcessingEnvironment processingEnv, boolean isValid, Element element,
|
|
||||||
List<TypeMirror> list, ArrayList<TypeElement> classTypeElements) {
|
|
||||||
for (var typeMirror : list) {
|
|
||||||
TypeElement typeElement = (TypeElement) processingEnv.getTypeUtils().asElement(typeMirror);
|
|
||||||
if (typeElement == null) {
|
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
|
||||||
"Could not get element for: " + typeMirror, element);
|
|
||||||
isValid = false;
|
|
||||||
} else {
|
|
||||||
classTypeElements.add(typeElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processPackages(ProcessingEnvironment processingEnv, List<TypeElement> classTypeElements,
|
|
||||||
List<String> packagesList) {
|
|
||||||
for (var packageName : packagesList) {
|
|
||||||
var packageElement = processingEnv.getElementUtils().getPackageElement(packageName);
|
|
||||||
for (var child : packageElement.getEnclosedElements()) {
|
|
||||||
if (child.getKind() == ElementKind.RECORD) {
|
|
||||||
classTypeElements.add((TypeElement) child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,10 +15,14 @@
|
|||||||
*/
|
*/
|
||||||
package io.soabase.recordbuilder.processor;
|
package io.soabase.recordbuilder.processor;
|
||||||
|
|
||||||
import com.squareup.javapoet.*;
|
import com.squareup.javapoet.ClassName;
|
||||||
|
import com.squareup.javapoet.MethodSpec;
|
||||||
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
|
import com.squareup.javapoet.TypeSpec;
|
||||||
|
import com.squareup.javapoet.TypeVariableName;
|
||||||
import io.soabase.recordbuilder.core.IgnoreDefaultMethod;
|
import io.soabase.recordbuilder.core.IgnoreDefaultMethod;
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
import io.soabase.recordbuilder.core.RecordBuilder;
|
||||||
|
import io.soabase.recordbuilder.core.RecordBuilderMetaData;
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
import javax.lang.model.element.ElementKind;
|
import javax.lang.model.element.ElementKind;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
@@ -26,76 +30,60 @@ import javax.lang.model.element.Modifier;
|
|||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
|
import static io.soabase.recordbuilder.processor.ElementUtils.getBuilderName;
|
||||||
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordInterfaceAnnotation;
|
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.generatedRecordInterfaceAnnotation;
|
||||||
import static io.soabase.recordbuilder.processor.RecordBuilderProcessor.recordBuilderGeneratedAnnotation;
|
|
||||||
|
|
||||||
class InternalRecordInterfaceProcessor {
|
class InternalRecordInterfaceProcessor {
|
||||||
private final ProcessingEnvironment processingEnv;
|
private final ProcessingEnvironment processingEnv;
|
||||||
private final String packageName;
|
private final String packageName;
|
||||||
private final TypeSpec recordType;
|
private final TypeSpec recordType;
|
||||||
private final List<Component> recordComponents;
|
private final List<ExecutableElement> recordComponents;
|
||||||
private final TypeElement iface;
|
private final TypeElement iface;
|
||||||
private final ClassType recordClassType;
|
private final ClassType recordClassType;
|
||||||
private final List<String> alternateMethods;
|
|
||||||
|
|
||||||
private static final String FAKE_METHOD_NAME = "__FAKE__";
|
private static final String FAKE_METHOD_NAME = "__FAKE__";
|
||||||
|
|
||||||
private static final Set<String> javaBeanPrefixes = Set.of("get", "is");
|
InternalRecordInterfaceProcessor(ProcessingEnvironment processingEnv, TypeElement iface, boolean addRecordBuilder, RecordBuilderMetaData metaData, Optional<String> packageNameOpt) {
|
||||||
|
|
||||||
private record Component(ExecutableElement element, Optional<String> alternateName) {
|
|
||||||
}
|
|
||||||
|
|
||||||
InternalRecordInterfaceProcessor(ProcessingEnvironment processingEnv, TypeElement iface, boolean addRecordBuilder,
|
|
||||||
RecordBuilder.Options metaData, Optional<String> packageNameOpt, boolean fromTemplate) {
|
|
||||||
this.processingEnv = processingEnv;
|
this.processingEnv = processingEnv;
|
||||||
packageName = packageNameOpt.orElseGet(() -> ElementUtils.getPackageName(iface));
|
packageName = packageNameOpt.orElseGet(() -> ElementUtils.getPackageName(iface));
|
||||||
recordComponents = getRecordComponents(iface);
|
recordComponents = getRecordComponents(iface);
|
||||||
this.iface = iface;
|
this.iface = iface;
|
||||||
|
|
||||||
ClassType ifaceClassType = ElementUtils.getClassType(iface, iface.getTypeParameters());
|
ClassType ifaceClassType = ElementUtils.getClassType(iface, iface.getTypeParameters());
|
||||||
recordClassType = ElementUtils.getClassType(packageName,
|
recordClassType = ElementUtils.getClassType(packageName, getBuilderName(iface, metaData, ifaceClassType, metaData.interfaceSuffix()), iface.getTypeParameters());
|
||||||
getBuilderName(iface, metaData, ifaceClassType, metaData.interfaceSuffix()), iface.getTypeParameters());
|
List<TypeVariableName> typeVariables = iface.getTypeParameters().stream().map(TypeVariableName::get).collect(Collectors.toList());
|
||||||
List<TypeVariableName> typeVariables = iface.getTypeParameters().stream().map(TypeVariableName::get)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
MethodSpec methodSpec = generateArgumentList();
|
MethodSpec methodSpec = generateArgumentList();
|
||||||
|
|
||||||
TypeSpec.Builder builder = TypeSpec.classBuilder(recordClassType.name()).addSuperinterface(iface.asType())
|
TypeSpec.Builder builder = TypeSpec.classBuilder(recordClassType.name())
|
||||||
.addMethod(methodSpec).addModifiers(Modifier.PUBLIC).addAnnotation(generatedRecordInterfaceAnnotation)
|
.addSuperinterface(iface.asType())
|
||||||
|
.addMethod(methodSpec)
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.addAnnotation(generatedRecordInterfaceAnnotation)
|
||||||
.addTypeVariables(typeVariables);
|
.addTypeVariables(typeVariables);
|
||||||
if (metaData.addClassRetainedGenerated()) {
|
|
||||||
builder.addAnnotation(recordBuilderGeneratedAnnotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addRecordBuilder) {
|
if (addRecordBuilder) {
|
||||||
ClassType builderClassType = ElementUtils.getClassType(packageName,
|
ClassType builderClassType = ElementUtils.getClassType(packageName, getBuilderName(iface, metaData, recordClassType, metaData.suffix()) + "." + metaData.withClassName(), iface.getTypeParameters());
|
||||||
getBuilderName(iface, metaData, recordClassType, metaData.suffix()) + "."
|
|
||||||
+ metaData.withClassName(),
|
|
||||||
iface.getTypeParameters());
|
|
||||||
builder.addAnnotation(RecordBuilder.class);
|
builder.addAnnotation(RecordBuilder.class);
|
||||||
builder.addSuperinterface(builderClassType.typeName());
|
builder.addSuperinterface(builderClassType.typeName());
|
||||||
if (fromTemplate) {
|
|
||||||
builder.addAnnotation(AnnotationSpec.get(metaData));
|
|
||||||
} else {
|
|
||||||
var options = iface.getAnnotation(RecordBuilder.Options.class);
|
|
||||||
if (options != null) {
|
|
||||||
builder.addAnnotation(AnnotationSpec.get(options));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alternateMethods = buildAlternateMethods(recordComponents);
|
|
||||||
|
|
||||||
recordType = builder.build();
|
recordType = builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isValid() {
|
boolean isValid()
|
||||||
|
{
|
||||||
return !recordComponents.isEmpty();
|
return !recordComponents.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,68 +99,53 @@ class InternalRecordInterfaceProcessor {
|
|||||||
return recordClassType;
|
return recordClassType;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toRecord(String classSource) {
|
String toRecord(String classSource)
|
||||||
|
{
|
||||||
// javapoet does yet support records - so a class was created and we can reshape it
|
// javapoet does yet support records - so a class was created and we can reshape it
|
||||||
// The class will look something like this:
|
// The class will look something like this:
|
||||||
/*
|
/*
|
||||||
* // Auto generated by io.soabase.recordbuilder.core.RecordBuilder: https://github.com/Randgalt/record-builder
|
// Auto generated by io.soabase.recordbuilder.core.RecordBuilder: https://github.com/Randgalt/record-builder
|
||||||
* package io.soabase.recordbuilder.test;
|
package io.soabase.recordbuilder.test;
|
||||||
*
|
|
||||||
* import io.soabase.recordbuilder.core.RecordBuilder; import javax.annotation.processing.Generated;
|
import io.soabase.recordbuilder.core.RecordBuilder;
|
||||||
*
|
import javax.annotation.processing.Generated;
|
||||||
* @Generated("io.soabase.recordbuilder.core.RecordInterface")
|
|
||||||
*
|
@Generated("io.soabase.recordbuilder.core.RecordInterface")
|
||||||
* @RecordBuilder public class MyRecord implements MyInterface { void __FAKE__(String name, int age) { } }
|
@RecordBuilder
|
||||||
*/
|
public class MyRecord implements MyInterface {
|
||||||
Pattern pattern = Pattern.compile("(.*)(implements.*)(\\{)(.*" + FAKE_METHOD_NAME + ")(\\(.*\\))(.*)",
|
void __FAKE__(String name, int age) {
|
||||||
Pattern.MULTILINE | Pattern.DOTALL);
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Pattern pattern = Pattern.compile("(.*)(implements.*)(\\{)(.*" + FAKE_METHOD_NAME + ")(\\(.*\\))(.*)", Pattern.MULTILINE | Pattern.DOTALL);
|
||||||
Matcher matcher = pattern.matcher(classSource);
|
Matcher matcher = pattern.matcher(classSource);
|
||||||
if (!matcher.find() || matcher.groupCount() != 6) {
|
if (!matcher.find() || matcher.groupCount() != 6) {
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Internal error generating record. Group count: " + matcher.groupCount(), iface);
|
||||||
"Internal error generating record. Group count: " + matcher.groupCount(), iface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String declaration = matcher.group(1).trim().replace("class", "record");
|
String declaration = matcher.group(1).trim().replace("class", "record");
|
||||||
String implementsSection = matcher.group(2).trim();
|
String implementsSection = matcher.group(2).trim();
|
||||||
String argumentList = matcher.group(5).trim();
|
String argumentList = matcher.group(5).trim();
|
||||||
|
return declaration + argumentList + " " + implementsSection + " {}";
|
||||||
StringBuilder fixedRecord = new StringBuilder(declaration).append(argumentList).append(' ')
|
|
||||||
.append(implementsSection).append(" {");
|
|
||||||
alternateMethods.forEach(method -> fixedRecord.append('\n').append(method));
|
|
||||||
fixedRecord.append('}');
|
|
||||||
return fixedRecord.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MethodSpec generateArgumentList() {
|
private MethodSpec generateArgumentList()
|
||||||
|
{
|
||||||
MethodSpec.Builder builder = MethodSpec.methodBuilder(FAKE_METHOD_NAME);
|
MethodSpec.Builder builder = MethodSpec.methodBuilder(FAKE_METHOD_NAME);
|
||||||
recordComponents.forEach(component -> {
|
recordComponents.forEach(element -> {
|
||||||
String name = component.alternateName.orElseGet(() -> component.element.getSimpleName().toString());
|
ParameterSpec parameterSpec = ParameterSpec.builder(ClassName.get(element.getReturnType()), element.getSimpleName().toString()).build();
|
||||||
ParameterSpec parameterSpec = ParameterSpec.builder(ClassName.get(component.element.getReturnType()), name)
|
builder.addTypeVariables(element.getTypeParameters().stream().map(TypeVariableName::get).collect(Collectors.toList()));
|
||||||
.build();
|
|
||||||
builder.addTypeVariables(component.element.getTypeParameters().stream().map(TypeVariableName::get)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
builder.addParameter(parameterSpec);
|
builder.addParameter(parameterSpec);
|
||||||
});
|
});
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> buildAlternateMethods(List<Component> recordComponents) {
|
private List<ExecutableElement> getRecordComponents(TypeElement iface) {
|
||||||
return recordComponents.stream().filter(component -> component.alternateName.isPresent()).map(component -> {
|
List<ExecutableElement> components = new ArrayList<>();
|
||||||
var method = MethodSpec.methodBuilder(component.element.getSimpleName().toString())
|
|
||||||
.addAnnotation(Override.class).addAnnotation(generatedRecordInterfaceAnnotation)
|
|
||||||
.returns(ClassName.get(component.element.getReturnType())).addModifiers(Modifier.PUBLIC)
|
|
||||||
.addCode("return $L();", component.alternateName.get()).build();
|
|
||||||
return method.toString();
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Component> getRecordComponents(TypeElement iface) {
|
|
||||||
List<Component> components = new ArrayList<>();
|
|
||||||
try {
|
try {
|
||||||
getRecordComponents(iface, components, new HashSet<>(), new HashSet<>());
|
getRecordComponents(iface, components, new HashSet<>(), new HashSet<>());
|
||||||
if (components.isEmpty()) {
|
if (components.isEmpty()) {
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Annotated interface has no component methods", iface);
|
||||||
"Annotated interface has no component methods", iface);
|
|
||||||
}
|
}
|
||||||
} catch (IllegalInterface e) {
|
} catch (IllegalInterface e) {
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), iface);
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), iface);
|
||||||
@@ -181,52 +154,40 @@ class InternalRecordInterfaceProcessor {
|
|||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class IllegalInterface extends RuntimeException {
|
private static class IllegalInterface extends RuntimeException
|
||||||
|
{
|
||||||
public IllegalInterface(String message) {
|
public IllegalInterface(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getRecordComponents(TypeElement iface, Collection<Component> components, Set<String> visitedSet,
|
private void getRecordComponents(TypeElement iface, Collection<? super ExecutableElement> components, Set<String> visitedSet, Set<String> usedNames) {
|
||||||
Set<String> usedNames) {
|
|
||||||
if (!visitedSet.add(iface.getQualifiedName().toString())) {
|
if (!visitedSet.add(iface.getQualifiedName().toString())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iface.getEnclosedElements().stream()
|
iface.getEnclosedElements().stream()
|
||||||
.filter(element -> (element.getKind() == ElementKind.METHOD)
|
.filter(element -> (element.getKind() == ElementKind.METHOD) && !(element.getModifiers().contains(Modifier.STATIC)))
|
||||||
&& !(element.getModifiers().contains(Modifier.STATIC)))
|
.map(element -> ((ExecutableElement) element))
|
||||||
.map(element -> ((ExecutableElement) element)).filter(element -> {
|
.filter(element -> {
|
||||||
if (element.isDefault()) {
|
if (element.isDefault()) {
|
||||||
return element.getAnnotation(IgnoreDefaultMethod.class) == null;
|
return element.getAnnotation(IgnoreDefaultMethod.class) == null;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).peek(element -> {
|
})
|
||||||
|
.peek(element -> {
|
||||||
if (!element.getParameters().isEmpty() || element.getReturnType().getKind() == TypeKind.VOID) {
|
if (!element.getParameters().isEmpty() || element.getReturnType().getKind() == TypeKind.VOID) {
|
||||||
throw new IllegalInterface(String.format(
|
throw new IllegalInterface(String.format("Non-static, non-default methods must take no arguments and must return a value. Bad method: %s.%s()", iface.getSimpleName(), element.getSimpleName()));
|
||||||
"Non-static, non-default methods must take no arguments and must return a value. Bad method: %s.%s()",
|
|
||||||
iface.getSimpleName(), element.getSimpleName()));
|
|
||||||
}
|
}
|
||||||
if (!element.getTypeParameters().isEmpty()) {
|
if (!element.getTypeParameters().isEmpty()) {
|
||||||
throw new IllegalInterface(
|
throw new IllegalInterface(String.format("Interface methods cannot have type parameters. Bad method: %s.%s()", iface.getSimpleName(), element.getSimpleName()));
|
||||||
String.format("Interface methods cannot have type parameters. Bad method: %s.%s()",
|
|
||||||
iface.getSimpleName(), element.getSimpleName()));
|
|
||||||
}
|
}
|
||||||
}).filter(element -> usedNames.add(element.getSimpleName().toString()))
|
})
|
||||||
.map(element -> new Component(element, stripBeanPrefix(element.getSimpleName().toString())))
|
.filter(element -> usedNames.add(element.getSimpleName().toString()))
|
||||||
.collect(Collectors.toCollection(() -> components));
|
.collect(Collectors.toCollection(() -> components));
|
||||||
iface.getInterfaces().forEach(parentIface -> {
|
iface.getInterfaces().forEach(parentIface -> {
|
||||||
TypeElement parentIfaceElement = (TypeElement) processingEnv.getTypeUtils().asElement(parentIface);
|
TypeElement parentIfaceElement = (TypeElement) processingEnv.getTypeUtils().asElement(parentIface);
|
||||||
getRecordComponents(parentIfaceElement, components, visitedSet, usedNames);
|
getRecordComponents(parentIfaceElement, components, visitedSet, usedNames);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> stripBeanPrefix(String name) {
|
|
||||||
return javaBeanPrefixes.stream().filter(prefix -> name.startsWith(prefix) && (name.length() > prefix.length()))
|
|
||||||
.findFirst().map(prefix -> {
|
|
||||||
var stripped = name.substring(prefix.length());
|
|
||||||
return Character.toLowerCase(stripped.charAt(0)) + stripped.substring(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2019 Jordan Zimmerman
|
||||||
|
*
|
||||||
|
* Licensed 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 io.soabase.recordbuilder.processor;
|
||||||
|
|
||||||
|
import io.soabase.recordbuilder.core.RecordBuilderMetaData;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class OptionBasedRecordBuilderMetaData implements RecordBuilderMetaData {
|
||||||
|
/**
|
||||||
|
* @see #suffix()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_SUFFIX = "suffix";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #interfaceSuffix()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_INTERFACE_SUFFIX = "interfaceSuffix";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #copyMethodName()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_COPY_METHOD_NAME = "copyMethodName";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #builderMethodName()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_BUILDER_METHOD_NAME = "builderMethodName";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #buildMethodName()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_BUILD_METHOD_NAME = "buildMethodName";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #componentsMethodName()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_COMPONENTS_METHOD_NAME = "componentsMethodName";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #fileComment()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_FILE_COMMENT = "fileComment";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #fileIndent()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_FILE_INDENT = "fileIndent";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #prefixEnclosingClassNames()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_PREFIX_ENCLOSING_CLASS_NAMES = "prefixEnclosingClassNames";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #withClassName()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_WITH_CLASS_NAME = "withClassName";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #withClassMethodPrefix()
|
||||||
|
*/
|
||||||
|
public static final String OPTION_WITH_CLASS_METHOD_PREFIX = "withClassMethodPrefix";
|
||||||
|
|
||||||
|
private final String suffix;
|
||||||
|
private final String interfaceSuffix;
|
||||||
|
private final String copyMethodName;
|
||||||
|
private final String builderMethodName;
|
||||||
|
private final String buildMethodName;
|
||||||
|
private final String componentsMethodName;
|
||||||
|
private final String withClassName;
|
||||||
|
private final String withClassMethodPrefix;
|
||||||
|
private final String fileComment;
|
||||||
|
private final String fileIndent;
|
||||||
|
private final boolean prefixEnclosingClassNames;
|
||||||
|
|
||||||
|
public OptionBasedRecordBuilderMetaData(Map<String, String> options) {
|
||||||
|
suffix = options.getOrDefault(OPTION_SUFFIX, DEFAULT.suffix());
|
||||||
|
interfaceSuffix = options.getOrDefault(OPTION_INTERFACE_SUFFIX, DEFAULT.interfaceSuffix());
|
||||||
|
builderMethodName = options.getOrDefault(OPTION_BUILDER_METHOD_NAME, DEFAULT.builderMethodName());
|
||||||
|
copyMethodName = options.getOrDefault(OPTION_COPY_METHOD_NAME, DEFAULT.copyMethodName());
|
||||||
|
buildMethodName = options.getOrDefault(OPTION_BUILD_METHOD_NAME, DEFAULT.buildMethodName());
|
||||||
|
componentsMethodName = options.getOrDefault(OPTION_COMPONENTS_METHOD_NAME, DEFAULT.componentsMethodName());
|
||||||
|
withClassName = options.getOrDefault(OPTION_WITH_CLASS_NAME, DEFAULT.withClassName());
|
||||||
|
withClassMethodPrefix = options.getOrDefault(OPTION_WITH_CLASS_METHOD_PREFIX, DEFAULT.withClassMethodPrefix());
|
||||||
|
fileComment = options.getOrDefault(OPTION_FILE_COMMENT, DEFAULT.fileComment());
|
||||||
|
fileIndent = options.getOrDefault(OPTION_FILE_INDENT, DEFAULT.fileIndent());
|
||||||
|
String prefixenclosingclassnamesopt = options.getOrDefault(OPTION_PREFIX_ENCLOSING_CLASS_NAMES, String.valueOf(DEFAULT.prefixEnclosingClassNames()));
|
||||||
|
if (prefixenclosingclassnamesopt == null) {
|
||||||
|
prefixEnclosingClassNames = true;
|
||||||
|
} else {
|
||||||
|
prefixEnclosingClassNames = Boolean.parseBoolean(prefixenclosingclassnamesopt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String suffix() {
|
||||||
|
return suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String copyMethodName() {
|
||||||
|
return copyMethodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String builderMethodName() {
|
||||||
|
return builderMethodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String buildMethodName() {
|
||||||
|
return buildMethodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String componentsMethodName() {
|
||||||
|
return componentsMethodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String withClassName() {
|
||||||
|
return withClassName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String withClassMethodPrefix() {
|
||||||
|
return withClassMethodPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fileComment() {
|
||||||
|
return fileComment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String fileIndent() {
|
||||||
|
return fileIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean prefixEnclosingClassNames() {
|
||||||
|
return prefixEnclosingClassNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String interfaceSuffix() {
|
||||||
|
return interfaceSuffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.processor;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.OptionalDouble;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import java.util.OptionalLong;
|
|
||||||
|
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
|
||||||
import com.squareup.javapoet.TypeName;
|
|
||||||
|
|
||||||
public record OptionalType(TypeName typeName, TypeName valueType) {
|
|
||||||
|
|
||||||
private static final TypeName optionalType = TypeName.get(Optional.class);
|
|
||||||
private static final TypeName optionalIntType = TypeName.get(OptionalInt.class);
|
|
||||||
private static final TypeName optionalLongType = TypeName.get(OptionalLong.class);
|
|
||||||
private static final TypeName optionalDoubleType = TypeName.get(OptionalDouble.class);
|
|
||||||
|
|
||||||
private static boolean isOptional(ClassType component) {
|
|
||||||
if (component.typeName().equals(optionalType)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return (component.typeName() instanceof ParameterizedTypeName parameterizedTypeName)
|
|
||||||
&& parameterizedTypeName.rawType.equals(optionalType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Optional<OptionalType> fromClassType(final ClassType component) {
|
|
||||||
if (isOptional(component)) {
|
|
||||||
if (!(component.typeName() instanceof ParameterizedTypeName parameterizedType)) {
|
|
||||||
return Optional.of(new OptionalType(optionalType, TypeName.get(Object.class)));
|
|
||||||
}
|
|
||||||
final TypeName containingType = parameterizedType.typeArguments.isEmpty() ? TypeName.get(Object.class)
|
|
||||||
: parameterizedType.typeArguments.get(0);
|
|
||||||
return Optional.of(new OptionalType(optionalType, containingType));
|
|
||||||
}
|
|
||||||
if (component.typeName().equals(optionalIntType)) {
|
|
||||||
return Optional.of(new OptionalType(optionalIntType, TypeName.get(int.class)));
|
|
||||||
}
|
|
||||||
if (component.typeName().equals(optionalLongType)) {
|
|
||||||
return Optional.of(new OptionalType(optionalLongType, TypeName.get(long.class)));
|
|
||||||
}
|
|
||||||
if (component.typeName().equals(optionalDoubleType)) {
|
|
||||||
return Optional.of(new OptionalType(optionalDoubleType, TypeName.get(double.class)));
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOptional() {
|
|
||||||
return typeName.equals(optionalType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2019 Jordan Zimmerman
|
||||||
|
*
|
||||||
|
* Licensed 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 io.soabase.recordbuilder.processor;
|
||||||
|
|
||||||
|
import io.soabase.recordbuilder.core.RecordBuilderMetaData;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
|
|
||||||
|
class RecordBuilderMetaDataLoader {
|
||||||
|
private final RecordBuilderMetaData metaData;
|
||||||
|
|
||||||
|
RecordBuilderMetaDataLoader(ProcessingEnvironment processingEnv, Consumer<String> logger) {
|
||||||
|
Map<String, String> options = processingEnv.getOptions();
|
||||||
|
String metaDataClassName = options.get(RecordBuilderMetaData.JAVAC_OPTION_NAME);
|
||||||
|
if ((metaDataClassName != null) && !metaDataClassName.isEmpty()) {
|
||||||
|
RecordBuilderMetaData loadedMetaData = null;
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName(metaDataClassName);
|
||||||
|
loadedMetaData = (RecordBuilderMetaData) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
logger.accept("Found meta data: " + clazz);
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
// log the thrown exception instead of the invocation target exception
|
||||||
|
logger.accept("Could not load meta data: " + metaDataClassName + " - " + e.getCause());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.accept("Could not load meta data: " + metaDataClassName + " - " + e);
|
||||||
|
}
|
||||||
|
metaData = (loadedMetaData != null) ? loadedMetaData : RecordBuilderMetaData.DEFAULT;
|
||||||
|
} else {
|
||||||
|
metaData = new OptionBasedRecordBuilderMetaData(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RecordBuilderMetaData getMetaData() {
|
||||||
|
return metaData;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.processor;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class RecordBuilderOptions {
|
|
||||||
private static final Map<String, Object> defaultValues = buildDefaultValues();
|
|
||||||
|
|
||||||
static RecordBuilder.Options build(Map<String, String> options) {
|
|
||||||
return (RecordBuilder.Options) Proxy.newProxyInstance(RecordBuilderOptions.class.getClassLoader(),
|
|
||||||
new Class[] { RecordBuilder.Options.class }, (proxy, method, args) -> {
|
|
||||||
var name = method.getName();
|
|
||||||
var defaultValue = defaultValues.get(name);
|
|
||||||
var option = options.get(name);
|
|
||||||
if (option != null) {
|
|
||||||
if (defaultValue instanceof String) {
|
|
||||||
return option;
|
|
||||||
}
|
|
||||||
if (defaultValue instanceof Boolean) {
|
|
||||||
return Boolean.parseBoolean(option);
|
|
||||||
}
|
|
||||||
if (defaultValue instanceof Integer) {
|
|
||||||
return Integer.parseInt(option);
|
|
||||||
}
|
|
||||||
if (defaultValue instanceof Long) {
|
|
||||||
return Long.parseLong(option);
|
|
||||||
}
|
|
||||||
if (defaultValue instanceof Double) {
|
|
||||||
return Double.parseDouble(option);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unhandled option type: " + defaultValue.getClass());
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, Object> buildDefaultValues() {
|
|
||||||
var workMap = new HashMap<String, Object>();
|
|
||||||
for (Method method : RecordBuilder.Options.class.getDeclaredMethods()) {
|
|
||||||
workMap.put(method.getName(), method.getDefaultValue());
|
|
||||||
}
|
|
||||||
workMap.put("toString", "Generated RecordBuilder.Options");
|
|
||||||
return Map.copyOf(workMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
private RecordBuilderOptions() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,9 +19,8 @@ import com.squareup.javapoet.AnnotationSpec;
|
|||||||
import com.squareup.javapoet.JavaFile;
|
import com.squareup.javapoet.JavaFile;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
import io.soabase.recordbuilder.core.RecordBuilder;
|
||||||
import io.soabase.recordbuilder.core.RecordBuilderGenerated;
|
import io.soabase.recordbuilder.core.RecordBuilderMetaData;
|
||||||
import io.soabase.recordbuilder.core.RecordInterface;
|
import io.soabase.recordbuilder.core.RecordInterface;
|
||||||
|
|
||||||
import javax.annotation.processing.AbstractProcessor;
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
import javax.annotation.processing.Filer;
|
import javax.annotation.processing.Filer;
|
||||||
import javax.annotation.processing.Generated;
|
import javax.annotation.processing.Generated;
|
||||||
@@ -30,6 +29,7 @@ import javax.lang.model.SourceVersion;
|
|||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
import javax.lang.model.element.PackageElement;
|
import javax.lang.model.element.PackageElement;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -44,28 +44,23 @@ public class RecordBuilderProcessor extends AbstractProcessor {
|
|||||||
private static final String RECORD_INTERFACE = RecordInterface.class.getName();
|
private static final String RECORD_INTERFACE = RecordInterface.class.getName();
|
||||||
private static final String RECORD_INTERFACE_INCLUDE = RecordInterface.Include.class.getName().replace('$', '.');
|
private static final String RECORD_INTERFACE_INCLUDE = RecordInterface.Include.class.getName().replace('$', '.');
|
||||||
|
|
||||||
static final AnnotationSpec generatedRecordBuilderAnnotation = AnnotationSpec.builder(Generated.class)
|
static final AnnotationSpec generatedRecordBuilderAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordBuilder.class.getName()).build();
|
||||||
.addMember("value", "$S", RecordBuilder.class.getName()).build();
|
static final AnnotationSpec generatedRecordInterfaceAnnotation = AnnotationSpec.builder(Generated.class).addMember("value", "$S", RecordInterface.class.getName()).build();
|
||||||
static final AnnotationSpec generatedRecordInterfaceAnnotation = AnnotationSpec.builder(Generated.class)
|
|
||||||
.addMember("value", "$S", RecordInterface.class.getName()).build();
|
|
||||||
static final AnnotationSpec recordBuilderGeneratedAnnotation = AnnotationSpec.builder(RecordBuilderGenerated.class)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation)
|
annotations.forEach(annotation -> roundEnv.getElementsAnnotatedWith(annotation).forEach(element -> process(annotation, element)));
|
||||||
.forEach(element -> process(annotation, element)));
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getSupportedAnnotationTypes() {
|
public Set<String> getSupportedAnnotationTypes() {
|
||||||
return Set.of("*");
|
return Set.of(RECORD_BUILDER, RECORD_BUILDER_INCLUDE, RECORD_INTERFACE, RECORD_INTERFACE_INCLUDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SourceVersion getSupportedSourceVersion() {
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
// we don't directly return RELEASE_14 as that may
|
// we don't directly return RELEASE_14 as that may
|
||||||
// not exist in prior releases
|
// not exist in prior releases
|
||||||
// if we're running on an older release, returning latest()
|
// if we're running on an older release, returning latest()
|
||||||
// is fine as we won't encounter any records anyway
|
// is fine as we won't encounter any records anyway
|
||||||
@@ -73,59 +68,64 @@ public class RecordBuilderProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void process(TypeElement annotation, Element element) {
|
private void process(TypeElement annotation, Element element) {
|
||||||
|
var metaData = new RecordBuilderMetaDataLoader(processingEnv, s -> processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, s)).getMetaData();
|
||||||
|
|
||||||
String annotationClass = annotation.getQualifiedName().toString();
|
String annotationClass = annotation.getQualifiedName().toString();
|
||||||
if (annotationClass.equals(RECORD_BUILDER)) {
|
if ( annotationClass.equals(RECORD_BUILDER) )
|
||||||
var typeElement = (TypeElement) element;
|
{
|
||||||
processRecordBuilder(typeElement, getMetaData(typeElement), Optional.empty());
|
processRecordBuilder((TypeElement)element, metaData, Optional.empty());
|
||||||
} else if (annotationClass.equals(RECORD_INTERFACE)) {
|
}
|
||||||
var typeElement = (TypeElement) element;
|
else if ( annotationClass.equals(RECORD_INTERFACE) )
|
||||||
processRecordInterface(typeElement, element.getAnnotation(RecordInterface.class).addRecordBuilder(),
|
{
|
||||||
getMetaData(typeElement), Optional.empty(), false);
|
processRecordInterface((TypeElement)element, element.getAnnotation(RecordInterface.class).addRecordBuilder(), metaData, Optional.empty());
|
||||||
} else if (annotationClass.equals(RECORD_BUILDER_INCLUDE) || annotationClass.equals(RECORD_INTERFACE_INCLUDE)) {
|
}
|
||||||
processIncludes(element, getMetaData(element), annotationClass);
|
else if ( annotationClass.equals(RECORD_BUILDER_INCLUDE) || annotationClass.equals(RECORD_INTERFACE_INCLUDE) )
|
||||||
} else {
|
{
|
||||||
var recordBuilderTemplate = annotation.getAnnotation(RecordBuilder.Template.class);
|
processIncludes(element, metaData, annotationClass);
|
||||||
if (recordBuilderTemplate != null) {
|
}
|
||||||
if (recordBuilderTemplate.asRecordInterface()) {
|
else
|
||||||
processRecordInterface((TypeElement) element, true, recordBuilderTemplate.options(),
|
{
|
||||||
Optional.empty(), true);
|
throw new RuntimeException("Unknown annotation: " + annotation);
|
||||||
} else {
|
|
||||||
processRecordBuilder((TypeElement) element, recordBuilderTemplate.options(), Optional.empty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecordBuilder.Options getMetaData(Element element) {
|
private void processIncludes(Element element, RecordBuilderMetaData metaData, String annotationClass) {
|
||||||
var recordSpecificMetaData = element.getAnnotation(RecordBuilder.Options.class);
|
|
||||||
return (recordSpecificMetaData != null) ? recordSpecificMetaData
|
|
||||||
: RecordBuilderOptions.build(processingEnv.getOptions());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processIncludes(Element element, RecordBuilder.Options metaData, String annotationClass) {
|
|
||||||
var isRecordBuilderInclude = annotationClass.equals(RECORD_BUILDER_INCLUDE);
|
|
||||||
var annotationMirrorOpt = ElementUtils.findAnnotationMirror(processingEnv, element, annotationClass);
|
var annotationMirrorOpt = ElementUtils.findAnnotationMirror(processingEnv, element, annotationClass);
|
||||||
if (annotationMirrorOpt.isEmpty()) {
|
if ( annotationMirrorOpt.isEmpty() )
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
{
|
||||||
"Could not get annotation mirror for: " + annotationClass, element);
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get annotation mirror for: " + annotationClass, element);
|
||||||
} else {
|
}
|
||||||
var includeHelper = new IncludeHelper(processingEnv, element, annotationMirrorOpt.get(),
|
else
|
||||||
isRecordBuilderInclude);
|
{
|
||||||
if (includeHelper.isValid()) {
|
var values = processingEnv.getElementUtils().getElementValuesWithDefaults(annotationMirrorOpt.get());
|
||||||
var packagePattern = ElementUtils.getStringAttribute(ElementUtils
|
var classes = ElementUtils.getAnnotationValue(values, "value");
|
||||||
.getAnnotationValue(includeHelper.getAnnotationValues(), "packagePattern").orElse(null), "*");
|
if ( classes.isEmpty() )
|
||||||
for (var typeElement : includeHelper.getClassTypeElements()) {
|
{
|
||||||
var packageName = buildPackageName(packagePattern, element, typeElement);
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get annotation value for: " + annotationClass, element);
|
||||||
if (packageName != null) {
|
}
|
||||||
if (isRecordBuilderInclude) {
|
else
|
||||||
|
{
|
||||||
|
var packagePattern = ElementUtils.getStringAttribute(ElementUtils.getAnnotationValue(values, "packagePattern").orElse(null), "*");
|
||||||
|
var classesMirrors = ElementUtils.getClassesAttribute(classes.get());
|
||||||
|
for ( TypeMirror mirror : classesMirrors )
|
||||||
|
{
|
||||||
|
TypeElement typeElement = (TypeElement)processingEnv.getTypeUtils().asElement(mirror);
|
||||||
|
if ( typeElement == null )
|
||||||
|
{
|
||||||
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Could not get element for: " + mirror, element);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var packageName = buildPackageName(packagePattern, element, typeElement);
|
||||||
|
if ( annotationClass.equals(RECORD_INTERFACE_INCLUDE) )
|
||||||
|
{
|
||||||
|
var addRecordBuilderOpt = ElementUtils.getAnnotationValue(values, "addRecordBuilder");
|
||||||
|
var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute).orElse(true);
|
||||||
|
processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
processRecordBuilder(typeElement, metaData, Optional.of(packageName));
|
processRecordBuilder(typeElement, metaData, Optional.of(packageName));
|
||||||
} else {
|
|
||||||
var addRecordBuilderOpt = ElementUtils
|
|
||||||
.getAnnotationValue(includeHelper.getAnnotationValues(), "addRecordBuilder");
|
|
||||||
var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute)
|
|
||||||
.orElse(true);
|
|
||||||
processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName),
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,97 +134,61 @@ public class RecordBuilderProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String buildPackageName(String packagePattern, Element builderElement, TypeElement includedClass) {
|
private String buildPackageName(String packagePattern, Element builderElement, TypeElement includedClass) {
|
||||||
PackageElement includedClassPackage = findPackageElement(includedClass, includedClass);
|
String replaced = packagePattern.replace("*", ((PackageElement)includedClass.getEnclosingElement()).getQualifiedName().toString());
|
||||||
if (includedClassPackage == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String replaced = packagePattern.replace("*", includedClassPackage.getQualifiedName().toString());
|
|
||||||
if (builderElement instanceof PackageElement) {
|
if (builderElement instanceof PackageElement) {
|
||||||
return replaced.replace("@", ((PackageElement) builderElement).getQualifiedName().toString());
|
return replaced.replace("@", ((PackageElement)builderElement).getQualifiedName().toString());
|
||||||
}
|
}
|
||||||
return replaced.replace("@",
|
return replaced.replace("@", ((PackageElement)builderElement.getEnclosingElement()).getQualifiedName().toString());
|
||||||
((PackageElement) builderElement.getEnclosingElement()).getQualifiedName().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PackageElement findPackageElement(Element actualElement, Element includedClass) {
|
private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilderMetaData metaData, Optional<String> packageName) {
|
||||||
if (includedClass == null) {
|
if ( !element.getKind().isInterface() )
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Element has not package", actualElement);
|
{
|
||||||
return null;
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordInterface only valid for interfaces.", element);
|
||||||
}
|
|
||||||
if (includedClass.getEnclosingElement() instanceof PackageElement) {
|
|
||||||
return (PackageElement) includedClass.getEnclosingElement();
|
|
||||||
}
|
|
||||||
return findPackageElement(actualElement, includedClass.getEnclosingElement());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilder.Options metaData,
|
|
||||||
Optional<String> packageName, boolean fromTemplate) {
|
|
||||||
if (!element.getKind().isInterface()) {
|
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
|
||||||
"RecordInterface only valid for interfaces.", element);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var internalProcessor = new InternalRecordInterfaceProcessor(processingEnv, element, addRecordBuilder, metaData, packageName);
|
||||||
validateMetaData(metaData, element);
|
if ( !internalProcessor.isValid() )
|
||||||
|
{
|
||||||
var internalProcessor = new InternalRecordInterfaceProcessor(processingEnv, element, addRecordBuilder, metaData,
|
|
||||||
packageName, fromTemplate);
|
|
||||||
if (!internalProcessor.isValid()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writeRecordInterfaceJavaFile(element, internalProcessor.packageName(), internalProcessor.recordClassType(),
|
writeRecordInterfaceJavaFile(element, internalProcessor.packageName(), internalProcessor.recordClassType(), internalProcessor.recordType(), metaData, internalProcessor::toRecord);
|
||||||
internalProcessor.recordType(), metaData, internalProcessor::toRecord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processRecordBuilder(TypeElement record, RecordBuilder.Options metaData,
|
private void processRecordBuilder(TypeElement record, RecordBuilderMetaData metaData, Optional<String> packageName) {
|
||||||
Optional<String> packageName) {
|
|
||||||
// we use string based name comparison for the element kind,
|
// we use string based name comparison for the element kind,
|
||||||
// as the ElementKind.RECORD enum doesn't exist on JRE releases
|
// as the ElementKind.RECORD enum doesn't exist on JRE releases
|
||||||
// older than Java 14, and we don't want to throw unexpected
|
// older than Java 14, and we don't want to throw unexpected
|
||||||
// NoSuchFieldErrors
|
// NoSuchFieldErrors
|
||||||
if (!"RECORD".equals(record.getKind().name())) {
|
if ( !"RECORD".equals(record.getKind().name()) )
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordBuilder only valid for records.",
|
{
|
||||||
record);
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "RecordBuilder only valid for records.", record);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var internalProcessor = new InternalRecordBuilderProcessor(record, metaData, packageName);
|
||||||
validateMetaData(metaData, record);
|
writeRecordBuilderJavaFile(record, internalProcessor.packageName(), internalProcessor.builderClassType(), internalProcessor.builderType(), metaData);
|
||||||
|
|
||||||
var internalProcessor = new InternalRecordBuilderProcessor(processingEnv, record, metaData, packageName);
|
|
||||||
writeRecordBuilderJavaFile(record, internalProcessor.packageName(), internalProcessor.builderClassType(),
|
|
||||||
internalProcessor.builderType(), metaData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateMetaData(RecordBuilder.Options metaData, Element record) {
|
private void writeRecordBuilderJavaFile(TypeElement record, String packageName, ClassType builderClassType, TypeSpec builderType, RecordBuilderMetaData metaData) {
|
||||||
var useImmutableCollections = metaData.useImmutableCollections();
|
|
||||||
var useUnmodifiableCollections = metaData.useUnmodifiableCollections();
|
|
||||||
|
|
||||||
if (useImmutableCollections && useUnmodifiableCollections) {
|
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING,
|
|
||||||
"Options.useUnmodifiableCollections property is ignored as Options.useImmutableCollections is set to true",
|
|
||||||
record);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeRecordBuilderJavaFile(TypeElement record, String packageName, ClassType builderClassType,
|
|
||||||
TypeSpec builderType, RecordBuilder.Options metaData) {
|
|
||||||
// produces the Java file
|
// produces the Java file
|
||||||
JavaFile javaFile = javaFileBuilder(packageName, builderType, metaData);
|
JavaFile javaFile = javaFileBuilder(packageName, builderType, metaData);
|
||||||
Filer filer = processingEnv.getFiler();
|
Filer filer = processingEnv.getFiler();
|
||||||
try {
|
try
|
||||||
String fullyQualifiedName = packageName.isEmpty() ? builderClassType.name()
|
{
|
||||||
: (packageName + "." + builderClassType.name());
|
String fullyQualifiedName = packageName.isEmpty() ? builderClassType.name() : (packageName + "." + builderClassType.name());
|
||||||
JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName);
|
JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName);
|
||||||
try (Writer writer = sourceFile.openWriter()) {
|
try (Writer writer = sourceFile.openWriter())
|
||||||
|
{
|
||||||
javaFile.writeTo(writer);
|
javaFile.writeTo(writer);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
handleWriteError(record, e);
|
handleWriteError(record, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeRecordInterfaceJavaFile(TypeElement element, String packageName, ClassType classType,
|
private void writeRecordInterfaceJavaFile(TypeElement element, String packageName, ClassType classType, TypeSpec type, RecordBuilderMetaData metaData, Function<String, String> toRecordProc) {
|
||||||
TypeSpec type, RecordBuilder.Options metaData, Function<String, String> toRecordProc) {
|
|
||||||
JavaFile javaFile = javaFileBuilder(packageName, type, metaData);
|
JavaFile javaFile = javaFileBuilder(packageName, type, metaData);
|
||||||
|
|
||||||
String classSourceCode = javaFile.toString();
|
String classSourceCode = javaFile.toString();
|
||||||
@@ -232,23 +196,26 @@ public class RecordBuilderProcessor extends AbstractProcessor {
|
|||||||
String recordSourceCode = toRecordProc.apply(classSourceCode);
|
String recordSourceCode = toRecordProc.apply(classSourceCode);
|
||||||
|
|
||||||
Filer filer = processingEnv.getFiler();
|
Filer filer = processingEnv.getFiler();
|
||||||
try {
|
try
|
||||||
String fullyQualifiedName = packageName.isEmpty() ? classType.name()
|
{
|
||||||
: (packageName + "." + classType.name());
|
String fullyQualifiedName = packageName.isEmpty() ? classType.name() : (packageName + "." + classType.name());
|
||||||
JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName);
|
JavaFileObject sourceFile = filer.createSourceFile(fullyQualifiedName);
|
||||||
try (Writer writer = sourceFile.openWriter()) {
|
try (Writer writer = sourceFile.openWriter())
|
||||||
|
{
|
||||||
writer.write(recordSourceCode);
|
writer.write(recordSourceCode);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
handleWriteError(element, e);
|
handleWriteError(element, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JavaFile javaFileBuilder(String packageName, TypeSpec type, RecordBuilder.Options metaData) {
|
private JavaFile javaFileBuilder(String packageName, TypeSpec type, RecordBuilderMetaData metaData) {
|
||||||
var javaFileBuilder = JavaFile.builder(packageName, type).skipJavaLangImports(true)
|
var javaFileBuilder = JavaFile.builder(packageName, type).skipJavaLangImports(true).indent(metaData.fileIndent());
|
||||||
.indent(metaData.fileIndent());
|
|
||||||
var comment = metaData.fileComment();
|
var comment = metaData.fileComment();
|
||||||
if ((comment != null) && !comment.isEmpty()) {
|
if ( (comment != null) && !comment.isEmpty() )
|
||||||
|
{
|
||||||
javaFileBuilder.addFileComment(comment);
|
javaFileBuilder.addFileComment(comment);
|
||||||
}
|
}
|
||||||
return javaFileBuilder.build();
|
return javaFileBuilder.build();
|
||||||
@@ -256,7 +223,8 @@ public class RecordBuilderProcessor extends AbstractProcessor {
|
|||||||
|
|
||||||
private void handleWriteError(TypeElement element, IOException e) {
|
private void handleWriteError(TypeElement element, IOException e) {
|
||||||
String message = "Could not create source file";
|
String message = "Could not create source file";
|
||||||
if (e.getMessage() != null) {
|
if ( e.getMessage() != null )
|
||||||
|
{
|
||||||
message = message + ": " + e.getMessage();
|
message = message + ": " + e.getMessage();
|
||||||
}
|
}
|
||||||
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
|
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, element);
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.processor;
|
|
||||||
|
|
||||||
import com.squareup.javapoet.TypeName;
|
|
||||||
|
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RecordClassType extends ClassType {
|
|
||||||
private final TypeName rawTypeName;
|
|
||||||
private final List<? extends AnnotationMirror> accessorAnnotations;
|
|
||||||
private final List<? extends AnnotationMirror> canonicalConstructorAnnotations;
|
|
||||||
|
|
||||||
public RecordClassType(TypeName typeName, TypeName rawTypeName, String name,
|
|
||||||
List<? extends AnnotationMirror> accessorAnnotations,
|
|
||||||
List<? extends AnnotationMirror> canonicalConstructorAnnotations) {
|
|
||||||
super(typeName, name);
|
|
||||||
this.rawTypeName = rawTypeName;
|
|
||||||
this.accessorAnnotations = accessorAnnotations;
|
|
||||||
this.canonicalConstructorAnnotations = canonicalConstructorAnnotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TypeName rawTypeName() {
|
|
||||||
return rawTypeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<? extends AnnotationMirror> getAccessorAnnotations() {
|
|
||||||
return accessorAnnotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<? extends AnnotationMirror> getCanonicalConstructorAnnotations() {
|
|
||||||
return canonicalConstructorAnnotations;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +1,18 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
|
||||||
|
|
||||||
Copyright 2019 The original author or authors
|
|
||||||
|
|
||||||
Licensed 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.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder</artifactId>
|
<artifactId>record-builder</artifactId>
|
||||||
<version>38-SNAPSHOT</version>
|
<version>1.11.ea</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>record-builder-test</artifactId>
|
<artifactId>record-builder-test</artifactId>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<license-file-path>${project.parent.basedir}/src/etc/header.txt</license-file-path>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>javax.validation</groupId>
|
|
||||||
<artifactId>validation-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder-processor</artifactId>
|
<artifactId>record-builder-core</artifactId>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
|
||||||
<artifactId>record-builder-validator</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate.validator</groupId>
|
|
||||||
<artifactId>hibernate-validator</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.glassfish</groupId>
|
|
||||||
<artifactId>javax.el</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -64,16 +20,31 @@
|
|||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<annotationProcessorPath>
|
||||||
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
|
<artifactId>record-builder-processor</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</annotationProcessorPath>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
<annotationProcessors>
|
||||||
|
<annotationProcessor>io.soabase.recordbuilder.processor.RecordBuilderProcessor</annotationProcessor>
|
||||||
|
</annotationProcessors>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-deploy-plugin</artifactId>
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
@@ -89,48 +60,6 @@
|
|||||||
<skip>true</skip>
|
<skip>true</skip>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.jacoco</groupId>
|
|
||||||
<artifactId>jacoco-maven-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>default-prepare-agent</id>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-agent</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>default-report</id>
|
|
||||||
<goals>
|
|
||||||
<goal>report</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>default-check</id>
|
|
||||||
<goals>
|
|
||||||
<goal>check</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<includes>
|
|
||||||
<include>io/soabase/recordbuilder/test/jacoco/*</include>
|
|
||||||
</includes>
|
|
||||||
<rules>
|
|
||||||
<rule>
|
|
||||||
<element>BUNDLE</element>
|
|
||||||
<limits>
|
|
||||||
<limit>
|
|
||||||
<counter>COMPLEXITY</counter>
|
|
||||||
<value>COVEREDRATIO</value>
|
|
||||||
<minimum>0.60</minimum>
|
|
||||||
</limit>
|
|
||||||
</limits>
|
|
||||||
</rule>
|
|
||||||
</rules>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
import javax.validation.constraints.Max;
|
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Null;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
public record Annotated(@NotNull @Null String hey, @Min(10) @Max(100) int i, double d) {
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordInterface;
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
@RecordInterface
|
|
||||||
public interface BeanStyle {
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
Instant getDate();
|
|
||||||
|
|
||||||
boolean isSomething();
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package io.soabase.recordbuilder.test;
|
package io.soabase.recordbuilder.test;
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
import io.soabase.recordbuilder.core.RecordInterface;
|
import io.soabase.recordbuilder.core.RecordInterface;
|
||||||
|
|
||||||
@RecordInterface.Include({ Thingy.class })
|
@RecordInterface.Include({
|
||||||
@RecordBuilder.Include({ Nested.NestedRecord.class })
|
Thingy.class
|
||||||
|
})
|
||||||
public class Builder {
|
public class Builder {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(addSingleItemCollectionBuilders = true, useImmutableCollections = true, mutableListClassName = "PersonalizedMutableList")
|
|
||||||
public record CollectionCopying<T>(List<String> list, Set<T> set, Map<Instant, T> map, Collection<T> collection,
|
|
||||||
int count) implements CollectionCopyingBuilder.With<T> {
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
import io.soabase.recordbuilder.core.RecordInterface;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordInterface
|
|
||||||
@RecordBuilder.Options(useImmutableCollections = true)
|
|
||||||
public interface CollectionInterface<T, X extends Point> {
|
|
||||||
List<T> l();
|
|
||||||
|
|
||||||
Set<T> s();
|
|
||||||
|
|
||||||
Map<T, X> m();
|
|
||||||
|
|
||||||
Collection<X> c();
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(useImmutableCollections = true, addFunctionalMethodsToWith = true)
|
|
||||||
public record CollectionRecord<T, X extends Point>(List<T> l, Set<T> s, Map<T, X> m, Collection<X> c)
|
|
||||||
implements CollectionRecordBuilder.With<T, X> {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
var r = new CollectionRecord<>(List.of("hey"), Set.of("there"), Map.of("one", new Point(10, 20)),
|
|
||||||
Set.of(new Point(30, 40)));
|
|
||||||
Instant now = r.map((l1, s1, m1, c1) -> Instant.now());
|
|
||||||
r.accept((l1, s1, m1, c1) -> {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(useImmutableCollections = true)
|
|
||||||
public record CollectionRecordConflicts(List<String> __list, Set<String> __set, Map<String, String> __map,
|
|
||||||
Collection<String> __collection) implements CollectionRecordConflictsBuilder.With {
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
import io.soabase.recordbuilder.test.CustomMethodNamesBuilder.Bean;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(setterPrefix = "set", getterPrefix = "get", booleanPrefix = "is", beanClassName = "Bean")
|
|
||||||
public record CustomMethodNames<K, V>(Map<K, V> kvMap, int theValue, List<Integer> theList, boolean theBoolean)
|
|
||||||
implements Bean, CustomMethodNamesBuilder.With {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
public record Empty() implements EmptyBuilder.With {
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.lang.model.type.ErrorType;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
public record ExceptionDetails(String internalMessage, String endUserMessage, String httpStatus, ErrorType errorType,
|
|
||||||
List<String> jsonProblems, Throwable cause) {
|
|
||||||
@Override
|
|
||||||
public List<String> jsonProblems() {
|
|
||||||
if (jsonProblems == null) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
return jsonProblems;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilderFull;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@RecordBuilderFull
|
|
||||||
public record FullRecord(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecord> fullRecords,
|
|
||||||
@NotNull String justAString) {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@RecordBuilder()
|
|
||||||
@RecordBuilder.Options(inheritComponentAnnotations = false)
|
|
||||||
public record IgnoreAnnotated(@NotNull String s) {
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder.Options(prefixEnclosingClassNames = false)
|
|
||||||
@RecordBuilder.Include(IncludeWithOption.Hey.class)
|
|
||||||
public class IncludeWithOption {
|
|
||||||
public static record Hey(String s) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
@MyInterfaceTemplate
|
|
||||||
public interface InterfaceTemplateTest {
|
|
||||||
String name();
|
|
||||||
|
|
||||||
int age();
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
public record MutableCollectionRecord(List<String> l) implements MutableCollectionRecordBuilder.With {
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder.Template(options = @RecordBuilder.Options(fileComment = "This is a test", withClassName = "Com"), asRecordInterface = true)
|
|
||||||
public @interface MyInterfaceTemplate {
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder.Template(options = @RecordBuilder.Options(fileComment = "This is a test", withClassName = "Com"))
|
|
||||||
public @interface MyTemplate {
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
public class Nested {
|
|
||||||
record NestedRecord(int x, int y) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copyright 2019 Jordan Zimmerman
|
|
||||||
*
|
|
||||||
* Licensed 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.
|
|
||||||
*/
|
|
||||||
@RecordBuilder.Options(addStaticBuilder = false)
|
|
||||||
@RecordBuilder
|
|
||||||
public record NoStaticBuilder(String foo) {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,5 +15,4 @@
|
|||||||
*/
|
*/
|
||||||
package io.soabase.recordbuilder.test;
|
package io.soabase.recordbuilder.test;
|
||||||
|
|
||||||
public record Pair<T, U>(T t, U u) {
|
public record Pair<T, U>(T t, U u) {}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,5 +15,4 @@
|
|||||||
*/
|
*/
|
||||||
package io.soabase.recordbuilder.test;
|
package io.soabase.recordbuilder.test;
|
||||||
|
|
||||||
public record Point(int x, int y) {
|
public record Point(int x, int y) {}
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
public record RecordWithAnR(int r, String b) {
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.OptionalDouble;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import java.util.OptionalLong;
|
|
||||||
|
|
||||||
@RecordBuilder.Options(emptyDefaultForOptional = true, addConcreteSettersForOptional = true)
|
|
||||||
@RecordBuilder
|
|
||||||
public record RecordWithOptional(@NotNull Optional<String> value, Optional raw, OptionalInt i, OptionalLong l,
|
|
||||||
OptionalDouble d) {
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.OptionalDouble;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import java.util.OptionalLong;
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder.Options(emptyDefaultForOptional = true)
|
|
||||||
@RecordBuilder
|
|
||||||
public record RecordWithOptional2(Optional<String> value, Optional raw, OptionalInt i, OptionalLong l,
|
|
||||||
OptionalDouble d) {
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(useValidationApi = true)
|
|
||||||
public record RequestWithValid(@NotNull @Valid Part part) implements RequestWithValidBuilder.With {
|
|
||||||
public record Part(@NotBlank String name) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RecordBuilder.Options(interpretNotNulls = true)
|
|
||||||
@RecordBuilder
|
|
||||||
public record RequiredRecord(@NotNull String hey, @NotNull int i, @NotNull List<String> l)
|
|
||||||
implements RequiredRecordBuilder.With {
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
@RecordBuilder.Options(useValidationApi = true)
|
|
||||||
@RecordBuilder
|
|
||||||
public record RequiredRecord2(@NotNull String hey, @NotNull int i) implements RequiredRecord2Builder.With {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,6 +18,5 @@ package io.soabase.recordbuilder.test;
|
|||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
import io.soabase.recordbuilder.core.RecordBuilder;
|
||||||
|
|
||||||
@RecordBuilder
|
@RecordBuilder
|
||||||
@RecordBuilder.Options(prefixEnclosingClassNames = false)
|
|
||||||
public record SimpleRecord(int i, String s) {
|
public record SimpleRecord(int i, String s) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(addSingleItemCollectionBuilders = true, singleItemBuilderPrefix = "add1", useImmutableCollections = true, addFunctionalMethodsToWith = true)
|
|
||||||
public record SingleItems<T>(List<String> strings, Set<List<T>> sets, Map<Instant, T> map, Collection<T> collection)
|
|
||||||
implements SingleItemsBuilder.With<T> {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(enableGetters = false, enableWither = false)
|
|
||||||
public record StrippedFeaturesRecord(int aField) {
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
@MyTemplate
|
|
||||||
public record TemplateTest(String text, Instant date) implements TemplateTestBuilder.Com {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(useUnmodifiableCollections = true)
|
|
||||||
record UnmodifiableCollectionsRecord(List<Integer> aList, Set<String> orderedSet, Map<String, Integer> orderedMap,
|
|
||||||
Collection<String> aCollection) {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
@RecordBuilder.Options(addSingleItemCollectionBuilders = true, useImmutableCollections = true)
|
|
||||||
public record WildcardSingleItems<T>(List<? extends String> strings, Set<? extends List<? extends T>> sets,
|
|
||||||
Map<? extends Instant, ? extends T> map, Collection<? extends T> collection)
|
|
||||||
implements WildcardSingleItemsBuilder.With<T> {
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder.Include(packages = "io.soabase.recordbuilder.test.includes.pack", classes = JustATest.class)
|
|
||||||
public class IncludeFactory {
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes;
|
|
||||||
|
|
||||||
public record JustATest(int i) {
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes.pack;
|
|
||||||
|
|
||||||
public interface AlsoIgnoreMe {
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes.pack;
|
|
||||||
|
|
||||||
public class IgnoreMe {
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes.pack;
|
|
||||||
|
|
||||||
public record PackRecord1(String name) {
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes.pack;
|
|
||||||
|
|
||||||
public record PackRecord2(String name, int age) {
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.includes.pack;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
public record PackRecord3(Instant time, int age) {
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.jacoco;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilderFull;
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilderGenerated;
|
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@RecordBuilderFull
|
|
||||||
@RecordBuilderGenerated
|
|
||||||
public record FullRecordForJacoco(@NotNull List<Number> numbers, @NotNull Map<Number, FullRecordForJacoco> fullRecords,
|
|
||||||
@NotNull String justAString) {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
@RecordBuilder.Include(value = { Point.class, Pair.class }, packagePattern = "*.foo")
|
|
||||||
@RecordBuilder.Options(fileComment = "MyLicense - Auto generated")
|
@RecordBuilder.Include(value = {Point.class, Pair.class}, packagePattern = "*.foo")
|
||||||
@RecordInterface.Include(value = Customer.class, addRecordBuilder = false, packagePattern = "*.bar")
|
@RecordInterface.Include(value = Customer.class, addRecordBuilder = false, packagePattern = "*.bar")
|
||||||
package io.soabase.recordbuilder.test;
|
package io.soabase.recordbuilder.test;
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.visibility;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
record PackagePrivateRecord(int i) {
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.visibility;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
import javax.lang.model.element.Modifier;
|
|
||||||
|
|
||||||
@RecordBuilder.Options(builderClassModifiers = { Modifier.PUBLIC })
|
|
||||||
@RecordBuilder
|
|
||||||
record PackagePrivateRecordWithPublicBuilder(String value) {
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test.visibility;
|
|
||||||
|
|
||||||
import io.soabase.recordbuilder.core.RecordBuilder;
|
|
||||||
|
|
||||||
class Wrapper {
|
|
||||||
@RecordBuilder
|
|
||||||
protected record ProtectedRecord(int i) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@RecordBuilder
|
|
||||||
record PackagePrivateRecord(int i) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import javax.validation.constraints.Max;
|
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
import javax.validation.constraints.Null;
|
|
||||||
import java.lang.reflect.AnnotatedElement;
|
|
||||||
|
|
||||||
class TestAnnotated {
|
|
||||||
@Test
|
|
||||||
void testInheritComponentAnnotationsFalse() throws NoSuchMethodException {
|
|
||||||
var method = IgnoreAnnotatedBuilder.class.getMethod("s");
|
|
||||||
Assertions.assertNull(method.getAnnotation(NotNull.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStaticConstructor() throws NoSuchMethodException {
|
|
||||||
var method = AnnotatedBuilder.class.getMethod("Annotated", String.class, Integer.TYPE, Double.TYPE);
|
|
||||||
var parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(3, parameters.length);
|
|
||||||
assertHey(parameters[0]);
|
|
||||||
assertI(parameters[1]);
|
|
||||||
assertD(parameters[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSetters() throws NoSuchMethodException {
|
|
||||||
var method = AnnotatedBuilder.class.getMethod("hey", String.class);
|
|
||||||
var parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(1, parameters.length);
|
|
||||||
assertHey(parameters[0]);
|
|
||||||
|
|
||||||
method = AnnotatedBuilder.class.getMethod("i", Integer.TYPE);
|
|
||||||
parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(1, parameters.length);
|
|
||||||
assertI(parameters[0]);
|
|
||||||
|
|
||||||
method = AnnotatedBuilder.class.getMethod("d", Double.TYPE);
|
|
||||||
parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(1, parameters.length);
|
|
||||||
assertD(parameters[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetters() throws NoSuchMethodException {
|
|
||||||
var method = AnnotatedBuilder.class.getMethod("hey");
|
|
||||||
assertHey(method);
|
|
||||||
|
|
||||||
method = AnnotatedBuilder.class.getMethod("i");
|
|
||||||
assertI(method);
|
|
||||||
|
|
||||||
method = AnnotatedBuilder.class.getMethod("d");
|
|
||||||
assertD(method);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testWitherSetters() throws NoSuchMethodException {
|
|
||||||
var method = AnnotatedBuilder.With.class.getMethod("withHey", String.class);
|
|
||||||
var parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(1, parameters.length);
|
|
||||||
assertHey(parameters[0]);
|
|
||||||
|
|
||||||
method = AnnotatedBuilder.With.class.getMethod("withI", Integer.TYPE);
|
|
||||||
parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(1, parameters.length);
|
|
||||||
assertI(parameters[0]);
|
|
||||||
|
|
||||||
method = AnnotatedBuilder.With.class.getMethod("withD", Double.TYPE);
|
|
||||||
parameters = method.getParameters();
|
|
||||||
Assertions.assertEquals(1, parameters.length);
|
|
||||||
assertD(parameters[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertD(AnnotatedElement d) {
|
|
||||||
Assertions.assertEquals(0, d.getAnnotations().length);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertI(AnnotatedElement i) {
|
|
||||||
Assertions.assertNotNull(i.getAnnotation(Min.class));
|
|
||||||
Assertions.assertEquals(i.getAnnotation(Min.class).value(), 10);
|
|
||||||
Assertions.assertNotNull(i.getAnnotation(Max.class));
|
|
||||||
Assertions.assertEquals(i.getAnnotation(Max.class).value(), 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertHey(AnnotatedElement hey) {
|
|
||||||
Assertions.assertNotNull(hey.getAnnotation(NotNull.class));
|
|
||||||
Assertions.assertNotNull(hey.getAnnotation(Null.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import static io.soabase.recordbuilder.test.foo.PointBuilder.Point;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class TestCollections {
|
|
||||||
@Test
|
|
||||||
void testRecordBuilderOptionsCopied() {
|
|
||||||
try {
|
|
||||||
assertNotNull(CollectionInterfaceRecordBuilder.class.getDeclaredMethod("__list", Collection.class));
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
Assertions.fail(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCollectionRecordDefaultValues() {
|
|
||||||
var defaultValues = CollectionRecordBuilder.builder().build();
|
|
||||||
assertNotNull(defaultValues.l());
|
|
||||||
assertNotNull(defaultValues.s());
|
|
||||||
assertNotNull(defaultValues.m());
|
|
||||||
assertNotNull(defaultValues.c());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCollectionRecordImmutable() {
|
|
||||||
var list = new ArrayList<String>();
|
|
||||||
list.add("one");
|
|
||||||
var set = new HashSet<String>();
|
|
||||||
set.add("one");
|
|
||||||
var map = new HashMap<String, Point>();
|
|
||||||
map.put("one", Point(10, 20));
|
|
||||||
var collectionAsSet = new HashSet<Point>();
|
|
||||||
collectionAsSet.add(Point(30, 40));
|
|
||||||
var r = CollectionRecordBuilder.<String, Point> builder().l(list).s(set).m(map).c(collectionAsSet).build();
|
|
||||||
|
|
||||||
assertValues(r, list, set, map, collectionAsSet);
|
|
||||||
assertValueChanges(r, list, set, map, collectionAsSet);
|
|
||||||
assertImmutable(r);
|
|
||||||
|
|
||||||
var collectionAsList = new ArrayList<Point>();
|
|
||||||
var x = CollectionRecordBuilder.<String, Point> builder().l(list).s(set).m(map).c(collectionAsList).build();
|
|
||||||
assertTrue(x.c() instanceof List);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCollectionRecordImmutableWithers() {
|
|
||||||
var r = CollectionRecordBuilder.<String, Point> builder().build();
|
|
||||||
|
|
||||||
var list = new ArrayList<String>();
|
|
||||||
list.add("one");
|
|
||||||
var set = new HashSet<String>();
|
|
||||||
set.add("one");
|
|
||||||
var map = new HashMap<String, Point>();
|
|
||||||
map.put("one", Point(10, 20));
|
|
||||||
var collectionAsSet = new HashSet<Point>();
|
|
||||||
collectionAsSet.add(Point(30, 40));
|
|
||||||
var x = r.withL(list).withS(set).withM(map).withC(collectionAsSet);
|
|
||||||
|
|
||||||
assertValues(x, list, set, map, collectionAsSet);
|
|
||||||
assertValueChanges(x, list, set, map, collectionAsSet);
|
|
||||||
assertImmutable(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMutableCollectionRecord() {
|
|
||||||
var r = MutableCollectionRecordBuilder.builder().build();
|
|
||||||
assertNull(r.l());
|
|
||||||
|
|
||||||
var list = new ArrayList<String>();
|
|
||||||
list.add("one");
|
|
||||||
r = MutableCollectionRecordBuilder.builder().l(list).build();
|
|
||||||
|
|
||||||
assertEquals(r.l(), list);
|
|
||||||
list.add("two");
|
|
||||||
assertEquals(r.l(), list);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertImmutable(CollectionRecord<String, Point> r) {
|
|
||||||
assertThrows(UnsupportedOperationException.class, () -> r.l().add("hey"));
|
|
||||||
assertThrows(UnsupportedOperationException.class, () -> r.s().add("hey"));
|
|
||||||
assertThrows(UnsupportedOperationException.class, () -> r.m().put("hey", Point(1, 2)));
|
|
||||||
assertThrows(UnsupportedOperationException.class, () -> r.c().add(Point(1, 2)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertValueChanges(CollectionRecord<String, Point> r, ArrayList<String> list, HashSet<String> set,
|
|
||||||
HashMap<String, Point> map, HashSet<Point> collectionAsSet) {
|
|
||||||
list.add("two");
|
|
||||||
set.add("two");
|
|
||||||
map.put("two", Point(50, 60));
|
|
||||||
collectionAsSet.add(Point(70, 80));
|
|
||||||
|
|
||||||
assertNotEquals(r.l(), list);
|
|
||||||
assertNotEquals(r.s(), set);
|
|
||||||
assertNotEquals(r.m(), map);
|
|
||||||
assertNotEquals(r.c(), collectionAsSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertValues(CollectionRecord<String, Point> r, ArrayList<String> list, HashSet<String> set,
|
|
||||||
HashMap<String, Point> map, HashSet<Point> collectionAsSet) {
|
|
||||||
assertEquals(r.l(), list);
|
|
||||||
assertEquals(r.s(), set);
|
|
||||||
assertEquals(r.m(), map);
|
|
||||||
assertEquals(r.c(), collectionAsSet);
|
|
||||||
assertTrue(r.c() instanceof Set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class TestCollectionsBuilder {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCollectionsBuilderReturnNonNullEmptyCollections() {
|
|
||||||
CollectionRecordBuilder<Object, Point> builder = CollectionRecordBuilder.builder();
|
|
||||||
|
|
||||||
Assertions.assertNotNull(builder.l());
|
|
||||||
Assertions.assertTrue(builder.l().isEmpty());
|
|
||||||
Assertions.assertNotNull(builder.c());
|
|
||||||
Assertions.assertTrue(builder.c().isEmpty());
|
|
||||||
Assertions.assertNotNull(builder.m());
|
|
||||||
Assertions.assertTrue(builder.m().isEmpty());
|
|
||||||
Assertions.assertNotNull(builder.s());
|
|
||||||
Assertions.assertTrue(builder.s().isEmpty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
public class TestImmutableCollections {
|
|
||||||
@Test
|
|
||||||
public void testImmutableListNotCopiedWhenNotChanged() {
|
|
||||||
var item = CollectionCopyingBuilder.<String> builder().addList("a").addList("b").addList("c").build();
|
|
||||||
Assertions.assertEquals(item.list(), List.of("a", "b", "c"));
|
|
||||||
|
|
||||||
var oldList = item.list();
|
|
||||||
|
|
||||||
var copy = item.with().count(1).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldList, copy.list());
|
|
||||||
|
|
||||||
var otherCopy = item.with().count(2).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldList, otherCopy.list());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testImmutableSetNotCopiedWhenNotChanged() {
|
|
||||||
var item = CollectionCopyingBuilder.<String> builder().addSet(Arrays.asList("1", "2", "3")).build();
|
|
||||||
Assertions.assertEquals(item.set(), Set.of("1", "2", "3"));
|
|
||||||
|
|
||||||
var oldSet = item.set();
|
|
||||||
|
|
||||||
var copy = item.with().count(1).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldSet, copy.set());
|
|
||||||
|
|
||||||
var otherCopy = item.with().count(2).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldSet, otherCopy.set());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testImmutableCollectionNotCopiedWhenNotChanged() {
|
|
||||||
var item = CollectionCopyingBuilder.<String> builder().collection(List.of("foo", "bar", "baz")).build();
|
|
||||||
Assertions.assertEquals(item.collection(), List.of("foo", "bar", "baz"));
|
|
||||||
|
|
||||||
var oldCollection = item.collection();
|
|
||||||
|
|
||||||
var copy = item.with().count(1).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldCollection, copy.collection());
|
|
||||||
|
|
||||||
var otherCopy = item.with().count(2).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldCollection, otherCopy.collection());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testImmutableMapNotCopiedWhenNotChanged() {
|
|
||||||
var item = CollectionCopyingBuilder.<String> builder().addMap(Instant.MAX, "future")
|
|
||||||
.addMap(Instant.MIN, "before").build();
|
|
||||||
Assertions.assertEquals(item.map(), Map.of(Instant.MAX, "future", Instant.MIN, "before"));
|
|
||||||
|
|
||||||
var oldMap = item.map();
|
|
||||||
|
|
||||||
var copy = item.with().count(1).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldMap, copy.map());
|
|
||||||
|
|
||||||
var otherCopy = item.with().count(2).build();
|
|
||||||
|
|
||||||
Assertions.assertSame(oldMap, otherCopy.map());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSourceListNotModified() {
|
|
||||||
var item = new CollectionCopying<>(new ArrayList<>(), null, null, null, 0);
|
|
||||||
var modifiedItem = CollectionCopyingBuilder.builder(item).addList("a").build();
|
|
||||||
|
|
||||||
Assertions.assertEquals(modifiedItem.list(), List.of("a"));
|
|
||||||
Assertions.assertTrue(item.list().isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSourceSetNotModified() {
|
|
||||||
var item = new CollectionCopying<>(null, new HashSet<>(), null, null, 0);
|
|
||||||
var modifiedItem = CollectionCopyingBuilder.builder(item).addSet("a").build();
|
|
||||||
|
|
||||||
Assertions.assertEquals(modifiedItem.set(), Set.of("a"));
|
|
||||||
Assertions.assertTrue(item.set().isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSourceMapNotModified() {
|
|
||||||
var item = new CollectionCopying<>(null, null, new HashMap<>(), null, 0);
|
|
||||||
var modifiedItem = CollectionCopyingBuilder.builder(item).addMap(Instant.MIN, "a").build();
|
|
||||||
|
|
||||||
Assertions.assertEquals(modifiedItem.map(), Map.of(Instant.MIN, "a"));
|
|
||||||
Assertions.assertTrue(item.map().isEmpty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class TestIncludes {
|
|
||||||
@Test
|
|
||||||
void testOptionsOnInclude() {
|
|
||||||
// assert it's not prefixed with the enclosing class name
|
|
||||||
IncludeWithOption.Hey hey = io.soabase.recordbuilder.test.HeyBuilder.builder().s("this is s").build();
|
|
||||||
Assertions.assertEquals("this is s", hey.s());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.OptionalDouble;
|
|
||||||
import java.util.OptionalInt;
|
|
||||||
import java.util.OptionalLong;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class TestOptional {
|
|
||||||
@Test
|
|
||||||
void testDefaultEmpty() {
|
|
||||||
var record = RecordWithOptionalBuilder.builder();
|
|
||||||
Assertions.assertEquals(Optional.empty(), record.value());
|
|
||||||
Assertions.assertEquals(Optional.empty(), record.raw());
|
|
||||||
Assertions.assertEquals(OptionalInt.empty(), record.i());
|
|
||||||
Assertions.assertEquals(OptionalLong.empty(), record.l());
|
|
||||||
Assertions.assertEquals(OptionalDouble.empty(), record.d());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRawSetters() {
|
|
||||||
var record = RecordWithOptionalBuilder.builder().value("value").raw("rawValue").i(42).l(424242L).d(42.42)
|
|
||||||
.build();
|
|
||||||
Assertions.assertEquals(Optional.of("value"), record.value());
|
|
||||||
Assertions.assertEquals(Optional.of("rawValue"), record.raw());
|
|
||||||
Assertions.assertEquals(OptionalInt.of(42), record.i());
|
|
||||||
Assertions.assertEquals(OptionalLong.of(424242L), record.l());
|
|
||||||
Assertions.assertEquals(OptionalDouble.of(42.42), record.d());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testOptionalSetters() {
|
|
||||||
var record = RecordWithOptional2Builder.builder().value(Optional.of("value")).raw(Optional.of("rawValue"))
|
|
||||||
.i(OptionalInt.of(42)).l(OptionalLong.of(424242L)).d(OptionalDouble.of(42.42)).build();
|
|
||||||
Assertions.assertEquals(Optional.of("value"), record.value());
|
|
||||||
Assertions.assertEquals(Optional.of("rawValue"), record.raw());
|
|
||||||
Assertions.assertEquals(OptionalInt.of(42), record.i());
|
|
||||||
Assertions.assertEquals(OptionalLong.of(424242L), record.l());
|
|
||||||
Assertions.assertEquals(OptionalDouble.of(42.42), record.d());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldAcceptNullForOptionalRawSetter() {
|
|
||||||
// given
|
|
||||||
String value = null;
|
|
||||||
|
|
||||||
// when
|
|
||||||
var record = RecordWithOptionalBuilder.builder().value(value).build();
|
|
||||||
|
|
||||||
// then
|
|
||||||
Assertions.assertEquals(Optional.empty(), record.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
class TestOptionsOnPackage {
|
|
||||||
@Test
|
|
||||||
void testOptionsOnInclude() throws IOException {
|
|
||||||
String text = Files.readString(
|
|
||||||
Path.of("target/generated-sources/annotations/io/soabase/recordbuilder/test/foo/PairBuilder.java"));
|
|
||||||
Assertions.assertTrue(text.contains("// MyLicense - Auto generated"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
class TestRecordBuilderFull {
|
|
||||||
@Test
|
|
||||||
void testNonNull() {
|
|
||||||
var record = FullRecordBuilder.builder().justAString("").build();
|
|
||||||
Assertions.assertEquals(List.of(), record.numbers());
|
|
||||||
Assertions.assertEquals(Map.of(), record.fullRecords());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testImmutable() {
|
|
||||||
var record = FullRecordBuilder.builder().fullRecords(new HashMap<>()).numbers(new ArrayList<>()).justAString("")
|
|
||||||
.build();
|
|
||||||
Assertions.assertThrows(UnsupportedOperationException.class, () -> record.fullRecords().put(1, record));
|
|
||||||
Assertions.assertThrows(UnsupportedOperationException.class, () -> record.numbers().add(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/**
|
||||||
* Copyright 2019 The original author or authors
|
* Copyright 2019 Jordan Zimmerman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,20 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package io.soabase.recordbuilder.test;
|
package io.soabase.recordbuilder.test;
|
||||||
|
|
||||||
import java.util.AbstractMap.SimpleImmutableEntry;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
import static io.soabase.recordbuilder.test.SimpleGenericRecordBuilder.SimpleGenericRecord;
|
public class TestRecordInterface
|
||||||
import static io.soabase.recordbuilder.test.SimpleRecordBuilder.SimpleRecord;
|
{
|
||||||
|
|
||||||
public class TestRecordInterface {
|
|
||||||
@Test
|
@Test
|
||||||
public void testHasDefaults() {
|
public void testHasDefaults()
|
||||||
|
{
|
||||||
var r1 = new HasDefaultsRecord(Instant.MIN, Instant.MAX);
|
var r1 = new HasDefaultsRecord(Instant.MIN, Instant.MAX);
|
||||||
var r2 = r1.with(b -> b.tomorrow(Instant.MIN));
|
var r2 = r1.with(b -> b.tomorrow(Instant.MIN));
|
||||||
Assertions.assertEquals(Instant.MIN, r1.time());
|
Assertions.assertEquals(Instant.MIN, r1.time());
|
||||||
@@ -36,29 +32,4 @@ public class TestRecordInterface {
|
|||||||
Assertions.assertEquals(Instant.MIN, r2.time());
|
Assertions.assertEquals(Instant.MIN, r2.time());
|
||||||
Assertions.assertEquals(Instant.MIN, r2.tomorrow());
|
Assertions.assertEquals(Instant.MIN, r2.tomorrow());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testStaticConstructor() {
|
|
||||||
var simple = SimpleRecord(10, "hey");
|
|
||||||
Assertions.assertEquals(simple.i(), 10);
|
|
||||||
Assertions.assertEquals(simple.s(), "hey");
|
|
||||||
|
|
||||||
var now = Instant.now();
|
|
||||||
var generic = SimpleGenericRecord(101, now);
|
|
||||||
Assertions.assertEquals(generic.i(), 101);
|
|
||||||
Assertions.assertEquals(generic.s(), now);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBuilderStreamWithValues() {
|
|
||||||
var stream = SimpleRecordBuilder.stream(SimpleRecordBuilder.builder().i(19).s("value").build()).toList();
|
|
||||||
Assertions.assertEquals(stream, List.of(Map.entry("i", 19), Map.entry("s", "value")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBuilderStreamWithNulls() {
|
|
||||||
var stream = SimpleRecordBuilder.stream(SimpleRecordBuilder.builder().build()).toList();
|
|
||||||
Assertions.assertEquals(stream,
|
|
||||||
List.of(new SimpleImmutableEntry<>("i", 0), new SimpleImmutableEntry<>("s", null)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class TestSingleItems {
|
|
||||||
@Test
|
|
||||||
public void testInternalCollections() {
|
|
||||||
var now = Instant.now();
|
|
||||||
var item = SingleItemsBuilder.<String> builder().add1Map(now, "now").add1Map(Instant.MIN, "before")
|
|
||||||
.add1Sets(Arrays.asList("1", "2")).add1Sets(List.of("3")).add1Strings("a").add1Strings("b")
|
|
||||||
.add1Strings("c").build();
|
|
||||||
Assertions.assertEquals(item.map(), Map.of(now, "now", Instant.MIN, "before"));
|
|
||||||
Assertions.assertEquals(item.sets(), Set.of(List.of("1", "2"), List.of("3")));
|
|
||||||
Assertions.assertEquals(item.strings(), List.of("a", "b", "c"));
|
|
||||||
|
|
||||||
var copy = item.with().add1Strings("new").add1Map(Instant.MAX, "after").add1Sets(List.of("10", "20", "30"))
|
|
||||||
.build();
|
|
||||||
Assertions.assertNotEquals(item, copy);
|
|
||||||
Assertions.assertEquals(copy.map(), Map.of(now, "now", Instant.MIN, "before", Instant.MAX, "after"));
|
|
||||||
Assertions.assertEquals(copy.sets(), Set.of(List.of("1", "2"), List.of("3"), List.of("10", "20", "30")));
|
|
||||||
Assertions.assertEquals(copy.strings(), List.of("a", "b", "c", "new"));
|
|
||||||
|
|
||||||
var stringsToAdd = Arrays.asList("x", "y", "z");
|
|
||||||
var listToAdd = Arrays.asList(List.of("aa", "bb"), List.of("cc"));
|
|
||||||
var mapToAdd = Map.of(now.plusMillis(1), "now+1", now.plusMillis(2), "now+2");
|
|
||||||
var streamed = SingleItemsBuilder.builder(item).add1Strings(stringsToAdd.stream()).add1Sets(listToAdd.stream())
|
|
||||||
.add1Map(mapToAdd.entrySet().stream()).build();
|
|
||||||
Assertions.assertEquals(streamed.map(),
|
|
||||||
Map.of(now, "now", Instant.MIN, "before", now.plusMillis(1), "now+1", now.plusMillis(2), "now+2"));
|
|
||||||
Assertions.assertEquals(streamed.sets(),
|
|
||||||
Set.of(List.of("1", "2"), List.of("3"), List.of("aa", "bb"), List.of("cc")));
|
|
||||||
Assertions.assertEquals(streamed.strings(), Arrays.asList("a", "b", "c", "x", "y", "z"));
|
|
||||||
|
|
||||||
var nulls = SingleItemsBuilder.builder(item).strings(null).sets(null).map(null).build();
|
|
||||||
Assertions.assertEquals(nulls.map(), Map.of());
|
|
||||||
Assertions.assertEquals(nulls.sets(), Set.of());
|
|
||||||
Assertions.assertEquals(nulls.strings(), List.of());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
class TestTemplate {
|
|
||||||
@Test
|
|
||||||
void testTemplate() {
|
|
||||||
var t = TemplateTestBuilder.TemplateTest("one", Instant.MIN);
|
|
||||||
var w = t.withText("other");
|
|
||||||
Assertions.assertEquals("one", t.text());
|
|
||||||
Assertions.assertEquals("other", w.text());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
|
|
||||||
public class TestUnmodifiableCollectionsBuilder {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldWrapCollectionsWithUnmodifiableView() {
|
|
||||||
// given
|
|
||||||
var list = new ArrayList<Integer>();
|
|
||||||
list.add(2);
|
|
||||||
list.add(1);
|
|
||||||
list.add(0);
|
|
||||||
|
|
||||||
var orderedSet = new LinkedHashSet<String>();
|
|
||||||
orderedSet.add("C");
|
|
||||||
orderedSet.add("B");
|
|
||||||
orderedSet.add("A");
|
|
||||||
|
|
||||||
var orderedMap = new LinkedHashMap<String, Integer>();
|
|
||||||
orderedMap.put("C", 2);
|
|
||||||
orderedMap.put("B", 1);
|
|
||||||
orderedMap.put("A", 0);
|
|
||||||
|
|
||||||
var collection = new HashSet<String>();
|
|
||||||
collection.add("C");
|
|
||||||
collection.add("B");
|
|
||||||
collection.add("A");
|
|
||||||
|
|
||||||
// when
|
|
||||||
var record = UnmodifiableCollectionsRecordBuilder.builder().aList(list).orderedSet(orderedSet)
|
|
||||||
.orderedMap(orderedMap).aCollection(collection).build();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertAll(() -> assertThrows(UnsupportedOperationException.class, () -> record.aList().add(9)),
|
|
||||||
() -> assertThat(record.aList()).containsExactly(2, 1, 0),
|
|
||||||
() -> assertThrows(UnsupportedOperationException.class, () -> record.orderedSet().add("newElement")),
|
|
||||||
() -> assertThat(record.orderedSet()).containsExactly("C", "B", "A"),
|
|
||||||
() -> assertThrows(UnsupportedOperationException.class, () -> record.orderedMap().put("newElement", 9)),
|
|
||||||
() -> assertThat(record.orderedMap()).containsExactly(entry("C", 2), entry("B", 1), entry("A", 0)),
|
|
||||||
() -> assertThrows(UnsupportedOperationException.class, () -> record.aCollection().add("newElement")),
|
|
||||||
() -> assertThat(record.aCollection()).containsExactlyInAnyOrder("C", "B", "A"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 The original author or authors
|
|
||||||
*
|
|
||||||
* Licensed 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 io.soabase.recordbuilder.test;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import javax.validation.ValidationException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class TestValidation {
|
|
||||||
@Test
|
|
||||||
void testNotNulls() {
|
|
||||||
Assertions.assertThrows(NullPointerException.class, () -> RequiredRecordBuilder.builder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testValidation() {
|
|
||||||
Assertions.assertThrows(ValidationException.class, () -> RequiredRecord2Builder.builder().build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNotNullsWithNewProperty() {
|
|
||||||
var valid = RequiredRecordBuilder.builder().hey("hey").i(1).l(List.of()).build();
|
|
||||||
Assertions.assertThrows(NullPointerException.class, () -> valid.withHey(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testValidationWithNewProperty() {
|
|
||||||
var valid = RequiredRecord2Builder.builder().hey("hey").i(1).build();
|
|
||||||
Assertions.assertThrows(ValidationException.class, () -> valid.withHey(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRequestWithValid() {
|
|
||||||
Assertions.assertDoesNotThrow(
|
|
||||||
() -> RequestWithValidBuilder.builder().part(new RequestWithValid.Part("jsfjsf")).build());
|
|
||||||
Assertions.assertThrows(ValidationException.class,
|
|
||||||
() -> RequestWithValidBuilder.builder().part(new RequestWithValid.Part("")).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user