Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.x: Inject update - collateral #8281

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,30 @@
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common-tls</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-apt</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-scan</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-compiler</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-class-model</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-helidon-copyright</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.common.processor</groupId>
<artifactId>helidon-common-processor</artifactId>
Expand Down Expand Up @@ -986,6 +1010,10 @@
<groupId>io.helidon.builder</groupId>
<artifactId>helidon-builder-processor</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.builder</groupId>
<artifactId>helidon-builder-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.inject</groupId>
<artifactId>helidon-inject-api</artifactId>
Expand Down
43 changes: 38 additions & 5 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,6 @@
<artifactId>helidon-security-integration-common</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.security.integration</groupId>
<artifactId>helidon-security-integration-webserver</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.security</groupId>
<artifactId>helidon-security-annotations</artifactId>
Expand Down Expand Up @@ -507,16 +502,49 @@
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-apt</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-scan</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-compiler</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-class-model</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-helidon-copyright</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<!-- deprecated module -->
<groupId>io.helidon.common.processor</groupId>
<artifactId>helidon-common-processor</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<!-- deprecated module -->
<groupId>io.helidon.common.processor</groupId>
<artifactId>helidon-common-processor-helidon-copyright</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<!-- deprecated module -->
<groupId>io.helidon.common.processor</groupId>
<artifactId>helidon-common-processor-class-model</artifactId>
<version>${helidon.version}</version>
Expand Down Expand Up @@ -1296,6 +1324,11 @@
<artifactId>helidon-builder-processor</artifactId>
<version>${helidon.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.builder</groupId>
<artifactId>helidon-builder-codegen</artifactId>
<version>${helidon.version}</version>
</dependency>

<!-- Injection Core -->
<dependency>
Expand Down
21 changes: 20 additions & 1 deletion builder/api/src/main/java/io/helidon/builder/api/Option.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
* Copyright (c) 2023, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -426,4 +426,23 @@ private Option() {
*/
String value();
}

/**
* Define an option decorator.
* This is useful for example when setting a compound option, where we need to set additional options on this builder.
* <p>
* Decorator on collection based options will be ignored.
* Decorator on optional values must accept an option (as it would be called both from the setter and unset methods).
*/
@Target(ElementType.METHOD)
// note: class retention needed for cases when derived builders are inherited across modules
@Retention(RetentionPolicy.CLASS)
public @interface Decorator {
/**
* Type declaration including generic types (must match the declared generic type on the blueprint).
*
* @return type name with generic declaration
*/
Class<? extends Prototype.OptionDecorator<?, ?>> value();
}
}
43 changes: 37 additions & 6 deletions builder/api/src/main/java/io/helidon/builder/api/Prototype.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
* Copyright (c) 2023, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -209,7 +209,7 @@ public interface Factory<T> {
public @interface Blueprint {
/**
* The generated interface is public by default. We can switch it to package local
* by setting this property to {@code false}-
* by setting this property to {@code false}.
*
* @return whether the generated interface should be public
*/
Expand All @@ -231,9 +231,10 @@ public interface Factory<T> {
boolean createFromConfigPublic() default true;

/**
* Method create() is public by default.
* Method create() is created whenever there are no fields required (or all have default values).
* This property can disable generation of the method.
*
* @return whether factory method create() should be public on prototype
* @return whether factory method create() should be created on prototype
*/
boolean createEmptyPublic() default true;

Expand Down Expand Up @@ -309,7 +310,7 @@ public interface Factory<T> {
* The builder provides accessors to all types, using {@link java.util.Optional} for any field that is optional,
* or any other field unless it has a default value. Primitive types are an exception (unless declared as required).
*
* @param <T> the type of the bean builder to intercept
* @param <T> the type of the builder to decorate
* @see io.helidon.builder.api.Prototype.Blueprint#decorator()
*/
@FunctionalInterface
Expand All @@ -322,6 +323,28 @@ public interface BuilderDecorator<T> {
void decorate(T target);
}

/**
* Provides a way to decorate a single option when it is applied to the builder.
* The decorator must have an accessible no argument constructor (at least package local).
*
* @param <B> the type of the builder to decorate
* @param <T> the type of the option to decorate
* @see io.helidon.builder.api.Prototype.Blueprint#decorator()
*/
@FunctionalInterface
public interface OptionDecorator<B, T> {
/**
* Provides the ability to decorate option as it is being set on the target builder.
* This method is invoked from within the setter of the value before the value is set on the builder (i.e. the
* builder still contains previous value).
* Do not call the same setter again from within this method, as it would end in a stack overflow.
*
* @param builder the target builder being decorated
* @param optionValue option value set by the caller of the setter method
*/
void decorate(B builder, T optionValue);
}

/**
* Adding this annotation in conjunction with the {@link Prototype.Blueprint} on a target interface
* type or method causes the {@link #value()} be added to the generated implementation class and methods respectfully.
Expand Down Expand Up @@ -407,6 +430,15 @@ public interface BuilderDecorator<T> {
public @interface PrototypeMethod {
}

/**
* Annotated constant of a custom methods type to be added to prototype interface.
* The constant will be generated as a reference to the annotated constant (so it must be package local).
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.CLASS)
public @interface Constant {
}

/**
* Add additional interfaces to implement by the prototype. Provide correct types (fully qualified) for generics.
*/
Expand All @@ -418,6 +450,5 @@ public interface BuilderDecorator<T> {
*/
String[] value();
}

}

58 changes: 58 additions & 0 deletions builder/codegen/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2022, 2024 Oracle and/or its affiliates.

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>io.helidon.builder</groupId>
<artifactId>helidon-builder-project</artifactId>
<version>4.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>helidon-builder-codegen</artifactId>
<name>Helidon Builder Code Generator</name>

<dependencies>
<dependency>
<groupId>io.helidon.common</groupId>
<artifactId>helidon-common-types</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen</artifactId>
</dependency>
<dependency>
<groupId>io.helidon.codegen</groupId>
<artifactId>helidon-codegen-class-model</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2023, 2024 Oracle and/or its affiliates.
*
* 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.helidon.builder.codegen;

import java.util.List;
import java.util.Set;

import io.helidon.common.types.TypeName;

record AnnotationDataBlueprint(
boolean prototypePublic,
boolean builderPublic,
boolean createFromConfigPublic,
boolean createEmptyPublic,
boolean isFactory,
Set<TypeName> extendsList,
String javadoc,
List<TypeName> typeArguments) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2023, 2024 Oracle and/or its affiliates.
*
* 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.helidon.builder.codegen;

import io.helidon.common.types.Annotation;
import io.helidon.common.types.TypeInfo;

record AnnotationDataConfigured(boolean configured, String rootPrefix, boolean isRoot) {
static AnnotationDataConfigured create(TypeInfo typeInfo) {
boolean configured = false;
boolean isRoot = false;
String prefix = null;

if (typeInfo.hasAnnotation(Types.PROTOTYPE_CONFIGURED)) {
configured = true;

Annotation annotation = typeInfo.annotation(Types.PROTOTYPE_CONFIGURED);
// if the annotation is present, the value has to be defined (may be empty string)
prefix = annotation.stringValue().orElse(null);
if (prefix != null) {
isRoot = annotation.booleanValue("root").orElse(true);
}
}

return new AnnotationDataConfigured(configured, prefix, isRoot);
}
}
Loading