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

Builder updates #6710

Merged
merged 5 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import io.helidon.builder.config.spi.ConfigBeanBuilderValidator;
import io.helidon.builder.config.spi.ConfigBeanInfo;
import io.helidon.builder.config.spi.ConfigResolver;
import io.helidon.builder.config.spi.DefaultConfigResolverRequest;
import io.helidon.builder.config.spi.ConfigResolverRequestDefault;
import io.helidon.builder.config.spi.GeneratedConfigBean;
import io.helidon.builder.config.spi.GeneratedConfigBeanBase;
import io.helidon.builder.config.spi.GeneratedConfigBeanBuilder;
Expand Down Expand Up @@ -325,12 +325,12 @@ protected void appendExtraBuilderMethods(StringBuilder builder,
}

builder.append("\t\t\tctx.resolver().").append(ofClause);
builder.append("(ctx, __metaAttributes(), ").append(DefaultConfigResolverRequest.class.getPackage().getName());
builder.append(".DefaultConfigResolver");
builder.append("(ctx, __metaAttributes(), ").append(ConfigResolverRequestDefault.class.getPackage().getName());
builder.append(".ConfigResolver");
if (isMap) {
builder.append("Map");
}
builder.append("Request.builder()\n\t\t\t\t\t");
builder.append("RequestDefault.builder()\n\t\t\t\t\t");
builder.append(".configKey(\"").append(configKey);
builder.append("\").attributeName(\"").append(attrName).append("\")");
builder.append(".valueType(").append(outerTypeName).append(".class)");
Expand Down
30 changes: 30 additions & 0 deletions builder/builder-config/etc/spotbugs/exclude.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2023 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.

-->

<FindBugsFilter
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://github.com/spotbugs/filter/3.0.0"
xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd">

<Match>
<!-- The invoked method is expected to have side effects -->
<Class name="io.helidon.builder.config.spi.ConfigBeanBuilderValidator$ValidationRound"/>
<Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" />
</Match>
</FindBugsFilter>
4 changes: 4 additions & 0 deletions builder/builder-config/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
<artifactId>helidon-builder-config</artifactId>
<name>Helidon Builder ConfigBean Builder</name>

<properties>
<spotbugs.exclude>etc/spotbugs/exclude.xml</spotbugs.exclude>
</properties>

<dependencies>
<dependency>
<groupId>io.helidon.builder</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
*
* @return true if repeatable
*/
boolean repeatable() default true;
boolean repeatable() default false;

/**
* An instance of this bean will be created if there are no instances discovered by the configuration provider(s) post
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@
*/
@FunctionalInterface
public interface ConfigBeanBuilderValidator<CBB> {
/**
* Validator that does nothing.
*
* @return empty typed validator
* @param <T> type of the config bean builder
*/
@SuppressWarnings("unchecked")
static <T> ConfigBeanBuilderValidator<T> empty() {
return (ConfigBeanBuilderValidator<T>) ConfigBeanBuilderValidatorHolder.EMPTY;
}

/**
* Creates a validation round for all the config bean attributes of the provided config bean.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

package io.helidon.builder.config.spi;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Supplier;

import io.helidon.common.HelidonServiceLoader;
import io.helidon.common.LazyValue;
Expand All @@ -28,6 +31,9 @@
* @see ConfigBeanBuilderValidatorProvider
*/
public class ConfigBeanBuilderValidatorHolder {
private static final ConfigBeanBuilderValidator.ValidationRound EMPTY_ROUND = new EmptyRound();
static final ConfigBeanBuilderValidator EMPTY = (builder, configBeanBuilderType) -> EMPTY_ROUND;

private static final LazyValue<Optional<ConfigBeanBuilderValidator<?>>> INSTANCE =
LazyValue.create(ConfigBeanBuilderValidatorHolder::load);

Expand Down Expand Up @@ -65,4 +71,29 @@ private static Optional<ConfigBeanBuilderValidator<?>> load() {
return Optional.of(provider.get().configBeanBuilderValidator());
}

private static class EmptyRound implements ConfigBeanBuilderValidator.ValidationRound {
@Override
public List<ConfigBeanBuilderValidator.ValidationIssue> issues() {
return List.of();
}

@Override
public boolean isCompleted() {
return true;
}

@Override
public ConfigBeanBuilderValidator.ValidationRound validate(String attributeName,
Supplier<?> valueSupplier,
Class<?> cbType,
Map<String, Object> meta) {
return this;
}

@Override
public ConfigBeanBuilderValidator.ValidationRound finish(boolean throwIfErrors) {
return this;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
* Represents all the attributes belonging to {@link io.helidon.builder.config.ConfigBean} available in a
* {@link io.helidon.builder.Builder} style usage pattern.
*/
@Builder(implPrefix = "Meta")
@Builder(implPrefix = "Meta", implSuffix = "")
public interface ConfigBeanInfo extends ConfigBean {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ public void __config(Config cfg) {
this.cfg = Objects.requireNonNull(cfg);
}

/**
* Update status of this builder from configuration, overriding existing values if config defines them.
*
* @param cfg configuration to update this builder from
tomas-langer marked this conversation as resolved.
Show resolved Hide resolved
*/
public void config(Config cfg) {
acceptConfig(cfg,
ConfigResolverHolder.configResolver().get(),
ConfigBeanBuilderValidator.empty());
}

/**
* Creates a resolution context.
*
Expand Down
3 changes: 2 additions & 1 deletion builder/builder-config/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
module io.helidon.builder.config {
requires static jakarta.annotation;
requires static jakarta.inject;
requires io.helidon.builder;
// used in generated code
requires transitive io.helidon.builder;
requires io.helidon.common;
requires io.helidon.common.config;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void testToMetaConfigBeanInfoFromConfigBean() {
ConfigBean cfg = Objects.requireNonNull(getClass().getAnnotation(ConfigBean.class));
MetaConfigBeanInfo metaCfg = ConfigBeanInfo.toMetaConfigBeanInfo(cfg, ConfigBean.class);
assertThat(metaCfg.annotationType(), sameInstance(ConfigBean.class));
assertThat(metaCfg.repeatable(), is(true));
assertThat(metaCfg.repeatable(), is(false));
assertThat(metaCfg.drivesActivation(), is(false));
assertThat(metaCfg.atLeastOne(), is(false));
assertThat(metaCfg.wantDefaultConfigBean(), is(false));
Expand Down
11 changes: 8 additions & 3 deletions builder/builder/src/main/java/io/helidon/builder/Builder.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,22 @@
/**
* The default prefix appended to the generated class name.
*/
String DEFAULT_IMPL_PREFIX = "Default";
String DEFAULT_IMPL_PREFIX = "";

/**
* The default prefix appended to the generated abstract class name (the parent for the {@link #DEFAULT_IMPL_PREFIX}).
*/
String DEFAULT_ABSTRACT_IMPL_PREFIX = "Abstract";
String DEFAULT_ABSTRACT_IMPL_PREFIX = "";

/**
* The default suffix appended to the generated abstract class name.
*/
String DEFAULT_ABSTRACT_IMPL_SUFFIX = "Base";

/**
* The default suffix appended to the generated class name(s).
*/
String DEFAULT_SUFFIX = "";
String DEFAULT_SUFFIX = "Default";

/**
* The default value for {@link #allowNulls()}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.helidon.builder.processor.tools;

import java.lang.annotation.Annotation;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand Down Expand Up @@ -63,6 +64,7 @@ public class DefaultBuilderCreatorProvider implements BuilderCreatorProvider {
static final boolean DEFAULT_REQUIRE_LIBRARY_DEPENDENCIES = true;
static final String DEFAULT_IMPL_PREFIX = Builder.DEFAULT_IMPL_PREFIX;
static final String DEFAULT_ABSTRACT_IMPL_PREFIX = Builder.DEFAULT_ABSTRACT_IMPL_PREFIX;
static final String DEFAULT_ABSTRACT_IMPL_SUFFIX = Builder.DEFAULT_ABSTRACT_IMPL_SUFFIX;
static final String DEFAULT_SUFFIX = Builder.DEFAULT_SUFFIX;
static final String DEFAULT_LIST_TYPE = Builder.DEFAULT_LIST_TYPE.getName();
static final String DEFAULT_MAP_TYPE = Builder.DEFAULT_MAP_TYPE.getName();
Expand Down Expand Up @@ -160,7 +162,7 @@ protected TypeName toAbstractImplTypeName(TypeName typeName,
AnnotationAndValue builderAnnotation) {
String toPackageName = toPackageName(typeName.packageName(), builderAnnotation);
String prefix = toAbstractImplTypePrefix(builderAnnotation);
String suffix = toImplTypeSuffix(builderAnnotation);
String suffix = toAbstractImplTypeSuffix(builderAnnotation);
return DefaultTypeName.create(toPackageName, prefix + typeName.className() + suffix);
}

Expand Down Expand Up @@ -1137,6 +1139,13 @@ private String toAbstractImplTypePrefix(AnnotationAndValue builderAnnotation) {
return builderAnnotation.value("abstractImplPrefix").orElse(DEFAULT_ABSTRACT_IMPL_PREFIX);
}

/**
* In support of {@link io.helidon.builder.Builder#abstractImplSuffix()}.
*/
private String toAbstractImplTypeSuffix(AnnotationAndValue builderAnnotation) {
return builderAnnotation.value("abstractImplSuffix").orElse(DEFAULT_ABSTRACT_IMPL_SUFFIX);
}

/**
* In support of {@link io.helidon.builder.Builder#implPrefix()}.
*/
Expand Down Expand Up @@ -1676,6 +1685,11 @@ private void appendDefaultValueAssignment(StringBuilder builder,
}
}

if (Duration.class.getName().equals(type.name())) {
builder.append("java.time.Duration.parse(\"").append(defaultVal).append("\")");
return;
}

boolean isString = type.name().equals(String.class.getName()) && !type.array();
boolean isCharArr = type.fqName().equals("char[]");
if ((isString || isCharArr) && !defaultVal.startsWith("\"")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
* Copyright (c) 2022, 2023 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 All @@ -21,11 +21,11 @@
/**
* See {@link InterceptedBean}.
*/
class BeanBuilderInterceptor implements BuilderInterceptor<DefaultInterceptedBean.Builder> {
class BeanBuilderInterceptor implements BuilderInterceptor<InterceptedBeanDefault.Builder> {
private int callCount;

@Override
public DefaultInterceptedBean.Builder intercept(DefaultInterceptedBean.Builder target) {
public InterceptedBeanDefault.Builder intercept(InterceptedBeanDefault.Builder target) {
if (callCount++ > 0) {
throw new AssertionError();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/**
* Demonstrate singular properties of maps and builders.
*/
@Builder(implPrefix = "Test")
@Builder(implPrefix = "Test", implSuffix = "")
public abstract class MapCase {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
* Copyright (c) 2022, 2023 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 All @@ -17,7 +17,7 @@
package io.helidon.builder.test;

import io.helidon.builder.test.testsubjects.AbstractWithCustomMethods;
import io.helidon.builder.test.testsubjects.DefaultAbstractWithCustomMethods;
import io.helidon.builder.test.testsubjects.AbstractWithCustomMethodsDefault;
import io.helidon.builder.test.testsubjects.GeneralInterceptor;

import org.junit.jupiter.api.Test;
Expand All @@ -32,7 +32,7 @@ class AbstractWithCustomMethodsTest {
*/
@Test
void testIt() {
AbstractWithCustomMethods val = DefaultAbstractWithCustomMethods.builder()
AbstractWithCustomMethods val = AbstractWithCustomMethodsDefault.builder()
.name("test")
.isStatic(true)
.isClass(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
* Copyright (c) 2022, 2023 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 All @@ -16,10 +16,10 @@

package io.helidon.builder.test;

import io.helidon.builder.test.testsubjects.DefaultTestNotNullable;
import io.helidon.builder.test.testsubjects.DefaultTestNullable;
import io.helidon.builder.test.testsubjects.TestNotNullable;
import io.helidon.builder.test.testsubjects.TestNotNullableDefault;
import io.helidon.builder.test.testsubjects.TestNullable;
import io.helidon.builder.test.testsubjects.TestNullableDefault;

import org.junit.jupiter.api.Test;

Expand All @@ -32,24 +32,24 @@ class AllowNullsTest {

@Test
void testIt() {
TestNullable nullable = DefaultTestNullable.builder().build();
TestNullable nullable = TestNullableDefault.builder().build();
assertThat(nullable.val(), nullValue());

nullable = DefaultTestNullable.builder().val(null).build();
nullable = TestNullableDefault.builder().val(null).build();
assertThat(nullable.val(), nullValue());

nullable = DefaultTestNullable.toBuilder(nullable).build();
nullable = TestNullableDefault.toBuilder(nullable).build();
assertThat(nullable.val(), nullValue());

TestNotNullable fake = () -> null;
try {
DefaultTestNotNullable.toBuilder(fake);
TestNotNullableDefault.toBuilder(fake);
fail();
} catch (NullPointerException e) {
// expected
}

DefaultTestNotNullable.Builder notNullableBuilder = DefaultTestNotNullable.builder();
TestNotNullableDefault.Builder notNullableBuilder = TestNotNullableDefault.builder();
assertThrows(NullPointerException.class, () -> notNullableBuilder.val(null));
assertThrows(IllegalStateException.class, notNullableBuilder::build);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
* Copyright (c) 2022, 2023 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 All @@ -19,7 +19,7 @@
import java.util.Arrays;

import io.helidon.builder.test.testsubjects.AnnotationCase;
import io.helidon.builder.test.testsubjects.DefaultAnnotationCaseExt;
import io.helidon.builder.test.testsubjects.AnnotationCaseExtDefault;

import org.junit.jupiter.api.Test;

Expand All @@ -32,7 +32,7 @@ class AnnotationCaseTest {

@Test
void testIt() {
DefaultAnnotationCaseExt annotationCase = DefaultAnnotationCaseExt.builder().build();
AnnotationCaseExtDefault annotationCase = AnnotationCaseExtDefault.builder().build();
assertThat(annotationCase.annotationType(), sameInstance(AnnotationCase.class));
assertThat(annotationCase.value(), equalTo("hello"));
assertThat(Arrays.asList(annotationCase.strArr()), contains("a", "b", "c"));
Expand Down
Loading