Skip to content

Commit 0839d48

Browse files
authored
Merge pull request #71 from SentryMan/customizer
Use Customizer instead of Bootstrap Config
2 parents c77469f + ecb923d commit 0839d48

File tree

16 files changed

+131
-56
lines changed

16 files changed

+131
-56
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package example.avaje.customizer;
2+
3+
import java.time.Clock;
4+
5+
import io.avaje.validation.Validator.Builder;
6+
import io.avaje.validation.spi.BuilderCustomizer;
7+
import io.avaje.validation.spi.ValidatorCustomizer;
8+
9+
@BuilderCustomizer
10+
public final class ClockCustomizer implements ValidatorCustomizer {
11+
12+
@Override
13+
public void customize(Builder builder) {
14+
builder.clockProvider(Clock::systemDefaultZone);
15+
}
16+
}

validator-generator/src/main/java/io/avaje/validation/generator/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ final class Constants {
66

77
static final String META_INF_COMPONENT =
88
"META-INF/services/io.avaje.validation.Validator$GeneratedComponent";
9+
static final String META_INF_CUSTOMIZER =
10+
"META-INF/services/io.avaje.validation.spi.ValidatorCustomizer";
911
public static final String VALID_SPI = "io.avaje.validation.spi.*";
1012
public static final String VALIDATOR = "io.avaje.validation.Validator";
1113
public static final String COMPONENT = "io.avaje.inject.Component";
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.avaje.validation.generator;
2+
3+
import static io.avaje.validation.generator.ProcessingContext.createMetaInfWriterFor;
4+
5+
import java.io.IOException;
6+
import java.io.UncheckedIOException;
7+
import java.util.Set;
8+
9+
import javax.lang.model.element.Element;
10+
import javax.lang.model.util.ElementFilter;
11+
12+
public class CustomizerServiceWriter {
13+
14+
private Append writer;
15+
private boolean eol;
16+
17+
CustomizerServiceWriter() {
18+
try {
19+
final var jfo = createMetaInfWriterFor(Constants.META_INF_CUSTOMIZER);
20+
writer = new Append(jfo.openWriter());
21+
} catch (final IOException e) {
22+
e.printStackTrace();
23+
throw new UncheckedIOException(e);
24+
}
25+
}
26+
27+
void writeMetaInf(Set<? extends Element> set) {
28+
for (final var element : ElementFilter.typesIn(set)) {
29+
final var fqn = element.getQualifiedName().toString();
30+
if (eol) {
31+
writer.eol().append(fqn);
32+
} else {
33+
writer.append(fqn);
34+
eol = true;
35+
}
36+
}
37+
}
38+
39+
void close() {
40+
writer.close();
41+
}
42+
}

validator-generator/src/main/java/io/avaje/validation/generator/SimpleComponentWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void writeMetaInf() throws IOException {
5454

5555
private void writeRegister() {
5656
writer.append(" @Override").eol();
57-
writer.append(" public void register(Validator.Builder builder) {").eol();
57+
writer.append(" public void customize(Validator.Builder builder) {").eol();
5858
final List<String> strings = metaData.allFactories();
5959
for (final String adapterFullName : strings) {
6060
final String adapterShortName = Util.shortName(adapterFullName);

validator-generator/src/main/java/io/avaje/validation/generator/ValidMethodReader.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static java.util.stream.Collectors.joining;
44

55
import java.util.List;
6-
import java.util.Map;
76
import java.util.Set;
87
import java.util.TreeSet;
98

validator-generator/src/main/java/io/avaje/validation/generator/ValidationProcessor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
@SupportedAnnotationTypes({
2828
AvajeValidPrism.PRISM_TYPE,
29+
BuilderCustomizerPrism.PRISM_TYPE,
2930
ImportValidPojoPrism.PRISM_TYPE,
3031
HttpValidPrism.PRISM_TYPE,
3132
JavaxValidPrism.PRISM_TYPE,
@@ -44,6 +45,7 @@ public final class ValidationProcessor extends AbstractProcessor {
4445
private final Set<String> mixInImports = new HashSet<>();
4546
private SimpleComponentWriter componentWriter;
4647
private boolean readModuleInfo;
48+
private CustomizerServiceWriter customizerServiceWriter;
4749

4850
@Override
4951
public SourceVersion getSupportedSourceVersion() {
@@ -55,6 +57,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
5557
super.init(processingEnv);
5658
ProcessingContext.init(processingEnv);
5759
this.componentWriter = new SimpleComponentWriter(metaData);
60+
this.customizerServiceWriter = new CustomizerServiceWriter();
5861
}
5962

6063
/** Read the existing metadata from the generated component (if exists). */
@@ -108,7 +111,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
108111
round.getElementsAnnotatedWith(element(ImportValidPojoPrism.PRISM_TYPE)));
109112
initialiseComponent();
110113
cascadeTypes();
111-
initialiseComponent();
114+
customizerServiceWriter.writeMetaInf(
115+
round.getElementsAnnotatedWith(element(BuilderCustomizerPrism.PRISM_TYPE)));
112116
writeComponent(round.processingOver());
113117
return false;
114118
}
@@ -184,6 +188,7 @@ private void initialiseComponent() {
184188
private void writeComponent(boolean processingOver) {
185189
if (processingOver) {
186190
try {
191+
customizerServiceWriter.close();
187192
componentWriter.write();
188193
componentWriter.writeMetaInf();
189194
} catch (final IOException e) {

validator-generator/src/main/java/io/avaje/validation/generator/package-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
@GeneratePrism(io.avaje.validation.spi.MetaData.AnnotationFactory.class)
2222
@GeneratePrism(io.avaje.validation.inject.aspect.ValidateMethod.class)
2323
@GeneratePrism(io.avaje.inject.Component.class)
24+
@GeneratePrism(io.avaje.validation.spi.BuilderCustomizer.class)
2425
package io.avaje.validation.generator;
2526

2627
import io.avaje.prism.GeneratePrism;

validator-generator/src/test/java/io/avaje/validation/generator/ValidatorProcessorTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ void deleteGeneratedFiles() throws IOException {
3333
.sorted(Comparator.reverseOrder())
3434
.map(Path::toFile)
3535
.forEach(File::delete);
36+
Paths.get("io.avaje.validation.spi.ValidatorCustomizer").toAbsolutePath().toFile().delete();
3637
Paths.get("io.avaje.validation.Validator$GeneratedComponent")
3738
.toAbsolutePath()
3839
.toFile()
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.avaje.validation.generator.models.valid;
2+
3+
import java.time.Clock;
4+
import java.time.ZoneId;
5+
6+
import io.avaje.validation.Validator.Builder;
7+
import io.avaje.validation.spi.BuilderCustomizer;
8+
import io.avaje.validation.spi.ValidatorCustomizer;
9+
10+
@BuilderCustomizer
11+
public final class ClockCustomizer implements ValidatorCustomizer {
12+
13+
@Override
14+
public void customize(Builder builder) {
15+
builder.clockProvider(() -> Clock.system(ZoneId.of("Anor Londo")));
16+
}
17+
}

validator/src/main/java/io/avaje/validation/Validator.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import io.avaje.lang.Nullable;
44
import io.avaje.validation.adapter.*;
55
import io.avaje.validation.core.DefaultBootstrap;
6-
import io.avaje.validation.spi.Bootstrap;
6+
import io.avaje.validation.spi.ValidatorCustomizer;
77

88
import java.lang.annotation.Annotation;
99
import java.lang.reflect.Type;
@@ -12,7 +12,6 @@
1212
import java.util.Locale;
1313
import java.util.Map;
1414
import java.util.ResourceBundle;
15-
import java.util.ServiceLoader;
1615
import java.util.Set;
1716
import java.util.function.Supplier;
1817

@@ -35,10 +34,7 @@ void validate(Object any, @Nullable Locale locale, @Nullable Class<?>... groups)
3534
ValidationContext getContext();
3635

3736
static Builder builder() {
38-
final var bootstrapService = ServiceLoader.load(Bootstrap.class).iterator();
39-
if (bootstrapService.hasNext()) {
40-
return bootstrapService.next().builder();
41-
}
37+
4238
return DefaultBootstrap.builder();
4339
}
4440

@@ -87,7 +83,7 @@ interface Builder {
8783
Builder add(Class<? extends Annotation> type, AnnotationAdapterBuilder builder);
8884

8985
/** Add a Component which can provide multiple ValidationAdapters and or configuration. */
90-
Builder add(ValidatorComponent component);
86+
Builder add(ValidatorCustomizer component);
9187

9288
/** Add a ValidationAdapter.Factory which provides ValidationAdapters to use. */
9389
Builder add(ValidationContext.AdapterFactory factory);
@@ -120,10 +116,10 @@ ValidationAdapter<?> build(
120116

121117
/** Components register ValidationAdapters Validator.Builder */
122118
@FunctionalInterface
123-
interface GeneratedComponent extends ValidatorComponent {
119+
interface GeneratedComponent extends ValidatorCustomizer {
124120

125-
/** Register ValidationAdapters with the Builder. */
121+
/** Customize the Builder with generated ValidationAdapters. */
126122
@Override
127-
void register(Builder builder);
123+
void customize(Builder builder);
128124
}
129125
}

validator/src/main/java/io/avaje/validation/adapter/ValidatorComponent.java

Lines changed: 0 additions & 19 deletions
This file was deleted.

validator/src/main/java/io/avaje/validation/core/DValidator.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
import io.avaje.validation.adapter.ValidationAdapter;
2828
import io.avaje.validation.adapter.ValidationContext;
2929
import io.avaje.validation.adapter.ValidationRequest;
30-
import io.avaje.validation.adapter.ValidatorComponent;
3130
import io.avaje.validation.spi.MessageInterpolator;
31+
import io.avaje.validation.spi.ValidatorCustomizer;
3232

3333
/** Default implementation of Validator. */
3434
final class DValidator implements Validator, ValidationContext {
@@ -195,8 +195,8 @@ public <T> Builder add(Type type, ValidationAdapter<T> adapter) {
195195
}
196196

197197
@Override
198-
public Builder add(ValidatorComponent component) {
199-
component.register(this);
198+
public Builder add(ValidatorCustomizer component) {
199+
component.customize(this);
200200
return this;
201201
}
202202

@@ -260,12 +260,12 @@ public Builder failFast(boolean failfast) {
260260
}
261261

262262
private void registerComponents() {
263-
// first register all user defined ValidatorComponent
264-
for (final ValidatorComponent next : ServiceLoader.load(ValidatorComponent.class)) {
265-
next.register(this);
263+
// first register all user defined ValidatorCustomizer
264+
for (final ValidatorCustomizer next : ServiceLoader.load(ValidatorCustomizer.class)) {
265+
next.customize(this);
266266
}
267267
for (final GeneratedComponent next : ServiceLoader.load(GeneratedComponent.class)) {
268-
next.register(this);
268+
next.customize(this);
269269
}
270270
}
271271

validator/src/main/java/io/avaje/validation/spi/Bootstrap.java

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.avaje.validation.spi;
2+
3+
import static java.lang.annotation.ElementType.TYPE;
4+
import static java.lang.annotation.RetentionPolicy.SOURCE;
5+
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.Target;
8+
/**
9+
* Registers a type extending ValidatorCustomizer to {@code META-INF/services}, annotated types will
10+
* have an entry added to {@code META-INF/services/io.avaje.validation.adapter.ValidatorCustomizer}
11+
*/
12+
@Retention(SOURCE)
13+
@Target(TYPE)
14+
public @interface BuilderCustomizer {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.avaje.validation.spi;
2+
3+
import io.avaje.validation.Validator;
4+
5+
/**
6+
* Callback interface that's used to customize a Validator.Builder.
7+
*
8+
* <p>These are service loaded when a Validator starts. The classes can be registered
9+
* with {@link BuilderCustomizer} or via a {@code provides} clause in module-info when using the java
10+
* module system.
11+
*/
12+
@FunctionalInterface
13+
public interface ValidatorCustomizer {
14+
15+
/** Callback to customize a Validator.Builder instance. */
16+
void customize(Validator.Builder builder);
17+
}

validator/src/main/java/module-info.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55

66
requires io.avaje.lang;
77

8-
uses io.avaje.validation.spi.Bootstrap;
98
uses io.avaje.validation.Validator.GeneratedComponent;
109
uses io.avaje.validation.spi.MessageInterpolator;
11-
uses io.avaje.validation.adapter.ValidatorComponent;
10+
uses io.avaje.validation.spi.ValidatorCustomizer;
1211
uses io.avaje.validation.adapter.ValidationContext.AdapterFactory;
1312
uses io.avaje.validation.adapter.ValidationContext.AnnotationFactory;
1413
}

0 commit comments

Comments
 (0)