Skip to content

Commit

Permalink
Merge pull request #71 from SentryMan/customizer
Browse files Browse the repository at this point in the history
Use Customizer instead of Bootstrap Config
  • Loading branch information
rbygrave authored Jul 13, 2023
2 parents c77469f + ecb923d commit 0839d48
Show file tree
Hide file tree
Showing 16 changed files with 131 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package example.avaje.customizer;

import java.time.Clock;

import io.avaje.validation.Validator.Builder;
import io.avaje.validation.spi.BuilderCustomizer;
import io.avaje.validation.spi.ValidatorCustomizer;

@BuilderCustomizer
public final class ClockCustomizer implements ValidatorCustomizer {

@Override
public void customize(Builder builder) {
builder.clockProvider(Clock::systemDefaultZone);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ final class Constants {

static final String META_INF_COMPONENT =
"META-INF/services/io.avaje.validation.Validator$GeneratedComponent";
static final String META_INF_CUSTOMIZER =
"META-INF/services/io.avaje.validation.spi.ValidatorCustomizer";
public static final String VALID_SPI = "io.avaje.validation.spi.*";
public static final String VALIDATOR = "io.avaje.validation.Validator";
public static final String COMPONENT = "io.avaje.inject.Component";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.avaje.validation.generator;

import static io.avaje.validation.generator.ProcessingContext.createMetaInfWriterFor;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Set;

import javax.lang.model.element.Element;
import javax.lang.model.util.ElementFilter;

public class CustomizerServiceWriter {

private Append writer;
private boolean eol;

CustomizerServiceWriter() {
try {
final var jfo = createMetaInfWriterFor(Constants.META_INF_CUSTOMIZER);
writer = new Append(jfo.openWriter());
} catch (final IOException e) {
e.printStackTrace();
throw new UncheckedIOException(e);
}
}

void writeMetaInf(Set<? extends Element> set) {
for (final var element : ElementFilter.typesIn(set)) {
final var fqn = element.getQualifiedName().toString();
if (eol) {
writer.eol().append(fqn);
} else {
writer.append(fqn);
eol = true;
}
}
}

void close() {
writer.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ void writeMetaInf() throws IOException {

private void writeRegister() {
writer.append(" @Override").eol();
writer.append(" public void register(Validator.Builder builder) {").eol();
writer.append(" public void customize(Validator.Builder builder) {").eol();
final List<String> strings = metaData.allFactories();
for (final String adapterFullName : strings) {
final String adapterShortName = Util.shortName(adapterFullName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static java.util.stream.Collectors.joining;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

@SupportedAnnotationTypes({
AvajeValidPrism.PRISM_TYPE,
BuilderCustomizerPrism.PRISM_TYPE,
ImportValidPojoPrism.PRISM_TYPE,
HttpValidPrism.PRISM_TYPE,
JavaxValidPrism.PRISM_TYPE,
Expand All @@ -44,6 +45,7 @@ public final class ValidationProcessor extends AbstractProcessor {
private final Set<String> mixInImports = new HashSet<>();
private SimpleComponentWriter componentWriter;
private boolean readModuleInfo;
private CustomizerServiceWriter customizerServiceWriter;

@Override
public SourceVersion getSupportedSourceVersion() {
Expand All @@ -55,6 +57,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
ProcessingContext.init(processingEnv);
this.componentWriter = new SimpleComponentWriter(metaData);
this.customizerServiceWriter = new CustomizerServiceWriter();
}

/** Read the existing metadata from the generated component (if exists). */
Expand Down Expand Up @@ -108,7 +111,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
round.getElementsAnnotatedWith(element(ImportValidPojoPrism.PRISM_TYPE)));
initialiseComponent();
cascadeTypes();
initialiseComponent();
customizerServiceWriter.writeMetaInf(
round.getElementsAnnotatedWith(element(BuilderCustomizerPrism.PRISM_TYPE)));
writeComponent(round.processingOver());
return false;
}
Expand Down Expand Up @@ -184,6 +188,7 @@ private void initialiseComponent() {
private void writeComponent(boolean processingOver) {
if (processingOver) {
try {
customizerServiceWriter.close();
componentWriter.write();
componentWriter.writeMetaInf();
} catch (final IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
@GeneratePrism(io.avaje.validation.spi.MetaData.AnnotationFactory.class)
@GeneratePrism(io.avaje.validation.inject.aspect.ValidateMethod.class)
@GeneratePrism(io.avaje.inject.Component.class)
@GeneratePrism(io.avaje.validation.spi.BuilderCustomizer.class)
package io.avaje.validation.generator;

import io.avaje.prism.GeneratePrism;
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void deleteGeneratedFiles() throws IOException {
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
Paths.get("io.avaje.validation.spi.ValidatorCustomizer").toAbsolutePath().toFile().delete();
Paths.get("io.avaje.validation.Validator$GeneratedComponent")
.toAbsolutePath()
.toFile()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.avaje.validation.generator.models.valid;

import java.time.Clock;
import java.time.ZoneId;

import io.avaje.validation.Validator.Builder;
import io.avaje.validation.spi.BuilderCustomizer;
import io.avaje.validation.spi.ValidatorCustomizer;

@BuilderCustomizer
public final class ClockCustomizer implements ValidatorCustomizer {

@Override
public void customize(Builder builder) {
builder.clockProvider(() -> Clock.system(ZoneId.of("Anor Londo")));
}
}
16 changes: 6 additions & 10 deletions validator/src/main/java/io/avaje/validation/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import io.avaje.lang.Nullable;
import io.avaje.validation.adapter.*;
import io.avaje.validation.core.DefaultBootstrap;
import io.avaje.validation.spi.Bootstrap;
import io.avaje.validation.spi.ValidatorCustomizer;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
Expand All @@ -12,7 +12,6 @@
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Supplier;

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

static Builder builder() {
final var bootstrapService = ServiceLoader.load(Bootstrap.class).iterator();
if (bootstrapService.hasNext()) {
return bootstrapService.next().builder();
}

return DefaultBootstrap.builder();
}

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

/** Add a Component which can provide multiple ValidationAdapters and or configuration. */
Builder add(ValidatorComponent component);
Builder add(ValidatorCustomizer component);

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

/** Components register ValidationAdapters Validator.Builder */
@FunctionalInterface
interface GeneratedComponent extends ValidatorComponent {
interface GeneratedComponent extends ValidatorCustomizer {

/** Register ValidationAdapters with the Builder. */
/** Customize the Builder with generated ValidationAdapters. */
@Override
void register(Builder builder);
void customize(Builder builder);
}
}

This file was deleted.

14 changes: 7 additions & 7 deletions validator/src/main/java/io/avaje/validation/core/DValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
import io.avaje.validation.adapter.ValidationAdapter;
import io.avaje.validation.adapter.ValidationContext;
import io.avaje.validation.adapter.ValidationRequest;
import io.avaje.validation.adapter.ValidatorComponent;
import io.avaje.validation.spi.MessageInterpolator;
import io.avaje.validation.spi.ValidatorCustomizer;

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

@Override
public Builder add(ValidatorComponent component) {
component.register(this);
public Builder add(ValidatorCustomizer component) {
component.customize(this);
return this;
}

Expand Down Expand Up @@ -260,12 +260,12 @@ public Builder failFast(boolean failfast) {
}

private void registerComponents() {
// first register all user defined ValidatorComponent
for (final ValidatorComponent next : ServiceLoader.load(ValidatorComponent.class)) {
next.register(this);
// first register all user defined ValidatorCustomizer
for (final ValidatorCustomizer next : ServiceLoader.load(ValidatorCustomizer.class)) {
next.customize(this);
}
for (final GeneratedComponent next : ServiceLoader.load(GeneratedComponent.class)) {
next.register(this);
next.customize(this);
}
}

Expand Down
15 changes: 0 additions & 15 deletions validator/src/main/java/io/avaje/validation/spi/Bootstrap.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.avaje.validation.spi;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Registers a type extending ValidatorCustomizer to {@code META-INF/services}, annotated types will
* have an entry added to {@code META-INF/services/io.avaje.validation.adapter.ValidatorCustomizer}
*/
@Retention(SOURCE)
@Target(TYPE)
public @interface BuilderCustomizer {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.avaje.validation.spi;

import io.avaje.validation.Validator;

/**
* Callback interface that's used to customize a Validator.Builder.
*
* <p>These are service loaded when a Validator starts. The classes can be registered
* with {@link BuilderCustomizer} or via a {@code provides} clause in module-info when using the java
* module system.
*/
@FunctionalInterface
public interface ValidatorCustomizer {

/** Callback to customize a Validator.Builder instance. */
void customize(Validator.Builder builder);
}
3 changes: 1 addition & 2 deletions validator/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@

requires io.avaje.lang;

uses io.avaje.validation.spi.Bootstrap;
uses io.avaje.validation.Validator.GeneratedComponent;
uses io.avaje.validation.spi.MessageInterpolator;
uses io.avaje.validation.adapter.ValidatorComponent;
uses io.avaje.validation.spi.ValidatorCustomizer;
uses io.avaje.validation.adapter.ValidationContext.AdapterFactory;
uses io.avaje.validation.adapter.ValidationContext.AnnotationFactory;
}

0 comments on commit 0839d48

Please sign in to comment.