Skip to content

Commit 1ca1227

Browse files
SentryManrbygrave
andauthored
Remove Avaje Spi Reliance (#217)
* remove avaje spi reliance * Update ComponentReader.java * Update ComponentReader.java * Format only changes --------- Co-authored-by: Rob Bygrave <[email protected]>
1 parent d9570eb commit 1ca1227

File tree

14 files changed

+76
-105
lines changed

14 files changed

+76
-105
lines changed

blackbox-test/src/main/resources/META-INF/services/io.avaje.jsonb.JsonbComponent

Lines changed: 0 additions & 1 deletion
This file was deleted.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<maven.compiler.release>17</maven.compiler.release>
3030
<inject.version>10.0-RC7</inject.version>
3131
<http.version>2.0-RC2</http.version>
32-
<spi.version>1.11</spi.version>
32+
<spi.version>2.0-RC1</spi.version>
3333
</properties>
3434

3535
<modules>
Lines changed: 12 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,10 @@
11
package io.avaje.validation.generator;
22

3-
import static io.avaje.validation.generator.APContext.typeElement;
4-
import static io.avaje.validation.generator.APContext.filer;
5-
import static io.avaje.validation.generator.APContext.logNote;
6-
import static io.avaje.validation.generator.APContext.logWarn;
3+
import java.util.Objects;
74

8-
import java.io.FileNotFoundException;
9-
import java.io.LineNumberReader;
10-
import java.io.Reader;
11-
import java.nio.file.NoSuchFileException;
12-
import java.util.ArrayList;
13-
import java.util.Collections;
14-
import java.util.List;
15-
16-
import javax.annotation.processing.FilerException;
175
import javax.lang.model.element.AnnotationMirror;
186
import javax.lang.model.element.TypeElement;
197
import javax.lang.model.type.TypeMirror;
20-
import javax.tools.FileObject;
21-
import javax.tools.StandardLocation;
228

239
final class ComponentReader {
2410

@@ -29,17 +15,18 @@ final class ComponentReader {
2915
}
3016

3117
void read() {
32-
final String componentFullName = loadMetaInfServices();
33-
if (componentFullName != null) {
34-
final TypeElement moduleType = typeElement(componentFullName);
35-
if (moduleType != null) {
36-
componentMetaData.setFullName(componentFullName);
18+
ProcessingContext.readExistingMetaInfServices().stream()
19+
.map(APContext::typeElement)
20+
.filter(Objects::nonNull)
21+
.filter(t -> "io.avaje.validation.spi.GeneratedComponent".equals(t.getSuperclass().toString()))
22+
.findFirst()
23+
.ifPresent(moduleType -> {
24+
componentMetaData.setFullName(moduleType.getQualifiedName().toString());
3725
readMetaData(moduleType);
38-
}
39-
}
26+
});
4027
}
4128

42-
/** Read the existing JsonAdapters from the MetaData annotation of the generated component. */
29+
/** Read the existing adapters from the MetaData annotation of the generated component. */
4330
private void readMetaData(TypeElement moduleType) {
4431
for (final AnnotationMirror annotationMirror : moduleType.getAnnotationMirrors()) {
4532
final MetaDataPrism metaData = MetaDataPrism.getInstance(annotationMirror);
@@ -54,47 +41,9 @@ private void readMetaData(TypeElement moduleType) {
5441

5542
} else if (metaDataAnnotationFactory != null) {
5643
metaDataAnnotationFactory.value().stream()
57-
.map(APContext::asTypeElement)
58-
.forEach(componentMetaData::addAnnotationAdapter);
44+
.map(APContext::asTypeElement)
45+
.forEach(componentMetaData::addAnnotationAdapter);
5946
}
6047
}
6148
}
62-
63-
private String loadMetaInfServices() {
64-
final List<String> lines = loadMetaInf();
65-
return lines.isEmpty() ? null : lines.get(0);
66-
}
67-
68-
private List<String> loadMetaInf() {
69-
try {
70-
final FileObject fileObject =
71-
filer()
72-
.getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT);
73-
74-
if (fileObject != null) {
75-
final List<String> lines = new ArrayList<>();
76-
final Reader reader = fileObject.openReader(true);
77-
final LineNumberReader lineReader = new LineNumberReader(reader);
78-
String line;
79-
while ((line = lineReader.readLine()) != null) {
80-
line = line.trim();
81-
if (!line.isEmpty()) {
82-
lines.add(line);
83-
}
84-
}
85-
return lines;
86-
}
87-
88-
} catch (FileNotFoundException | NoSuchFileException e) {
89-
// logDebug("no services file yet");
90-
91-
} catch (final FilerException e) {
92-
logNote("FilerException reading services file");
93-
94-
} catch (final Exception e) {
95-
e.printStackTrace();
96-
logWarn("Error reading services file: " + e.getMessage());
97-
}
98-
return Collections.emptyList();
99-
}
10049
}

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

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
import static io.avaje.validation.generator.APContext.logWarn;
77
import static java.util.stream.Collectors.toSet;
88

9+
import java.io.BufferedReader;
910
import java.io.IOException;
11+
import java.io.InputStreamReader;
1012
import java.net.URI;
1113
import java.net.URISyntaxException;
14+
import java.util.HashSet;
15+
import java.util.Set;
16+
import java.util.TreeSet;
17+
1218
import javax.annotation.processing.ProcessingEnvironment;
1319
import javax.tools.FileObject;
1420
import javax.tools.StandardLocation;
15-
1621
import io.avaje.validation.generator.ModuleInfoReader.Requires;
1722

1823
final class ProcessingContext {
@@ -23,14 +28,13 @@ private static final class Ctx {
2328
private final String diAnnotation;
2429
private final boolean warnHttp;
2530
private final boolean injectPresent;
26-
private final boolean spiPresent;
27-
private boolean validated;
31+
private final Set<String> serviceSet = new TreeSet<>();
2832

2933
Ctx(ProcessingEnvironment env) {
3034
var elements = env.getElementUtils();
35+
3136
this.injectPresent = elements.getTypeElement(Constants.COMPONENT) != null;
3237
this.warnHttp = elements.getTypeElement("io.avaje.http.api.Controller") != null;
33-
this.spiPresent = elements.getTypeElement("io.avaje.spi.internal.ServiceProcessor") != null;
3438

3539
final var jakarta = elements.getTypeElement(Constants.SINGLETON_JAKARTA) != null;
3640
diAnnotation =
@@ -48,28 +52,24 @@ static void init(ProcessingEnvironment processingEnv) {
4852
}
4953

5054
static FileObject createMetaInfWriterFor(String interfaceType) throws IOException {
51-
var serviceFile =
52-
CTX.get().spiPresent
53-
? interfaceType.replace("META-INF/services/", "META-INF/generated-services/")
54-
: interfaceType;
55-
56-
return filer().createResource(StandardLocation.CLASS_OUTPUT, "", serviceFile);
55+
return filer().createResource(StandardLocation.CLASS_OUTPUT, "", interfaceType);
5756
}
5857

5958
static String diAnnotation() {
6059
return CTX.get().diAnnotation;
6160
}
6261

63-
static void validateModule(String fqn) {
62+
static void validateModule() {
6463
var module = getProjectModuleElement();
65-
if (module != null && !CTX.get().validated && !module.isUnnamed()) {
66-
67-
CTX.get().validated = true;
64+
if (module != null && !module.isUnnamed()) {
6865
var injectPresent = CTX.get().injectPresent;
6966
var warnHttp = CTX.get().warnHttp;
7067

7168
try (var reader = getModuleInfoReader()) {
7269
var moduleInfo = new ModuleInfoReader(module, reader);
70+
71+
moduleInfo.validateServices("io.avaje.validation.spi.ValidationExtension", CTX.get().serviceSet);
72+
7373
var buildPluginAvailable = buildPluginAvailable();
7474
var requireSet =
7575
moduleInfo.requires().stream()
@@ -90,9 +90,9 @@ static void validateModule(String fqn) {
9090
&& !moduleInfo.containsOnModulePath("io.avaje.validation.plugin");
9191

9292
if (noHttpPlugin) {
93-
logWarn(module, "`requires io.avaje.validation.http` must be explicity added or else avaje-inject may fail to detect the default http validator, validator, and method AOP validator", fqn);
93+
logWarn(module, "`requires io.avaje.validation.http` must be explicity added or else avaje-inject may fail to detect the default http validator, validator, and method AOP validator");
9494
} else if (noInjectPlugin) {
95-
logWarn(module, "`requires io.avaje.validation.plugin` must be explicity added or else avaje-inject may fail to detect the default validator and method AOP validator", fqn);
95+
logWarn(module, "`requires io.avaje.validation.plugin` must be explicity added or else avaje-inject may fail to detect the default validator and method AOP validator");
9696
}
9797

9898
} catch (Exception e) {
@@ -121,8 +121,32 @@ private static boolean resource(String relativeName, String replace) {
121121
}
122122
}
123123

124+
static Set<String> readExistingMetaInfServices() {
125+
var services = CTX.get().serviceSet;
126+
try (final var file =
127+
APContext.filer()
128+
.getResource(StandardLocation.CLASS_OUTPUT, "", Constants.META_INF_COMPONENT)
129+
.toUri()
130+
.toURL()
131+
.openStream();
132+
final var buffer = new BufferedReader(new InputStreamReader(file));) {
133+
134+
String line;
135+
while ((line = buffer.readLine()) != null) {
136+
line.replaceAll("\\s", "").replace(",", "\n").lines().forEach(services::add);
137+
}
138+
} catch (Exception e) {
139+
// not a critical error
140+
}
141+
return services;
142+
}
143+
124144
static void clear() {
125145
CTX.remove();
126146
APContext.clear();
127147
}
148+
149+
public static void addValidatorSpi(String spi) {
150+
CTX.get().serviceSet.add(spi);
151+
}
128152
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void initialise() throws IOException {
2929
fileObject = createSourceFile(name);
3030
}
3131
if (!metaData.isEmpty()) {
32-
ProcessingContext.validateModule(name);
32+
ProcessingContext.validateModule();
3333
}
3434
}
3535

@@ -48,10 +48,12 @@ void write() throws IOException {
4848
}
4949

5050
void writeMetaInf() throws IOException {
51+
var services = ProcessingContext.readExistingMetaInfServices();
5152
final FileObject fileObject = createMetaInfWriterFor(Constants.META_INF_COMPONENT);
5253
if (fileObject != null) {
5354
try (Writer writer = fileObject.openWriter()) {
54-
writer.write(metaData.fullName());
55+
services.add(metaData.fullName());
56+
writer.write(String.join("\n", services));
5557
}
5658
}
5759
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
JakartaConstraintPrism.PRISM_TYPE,
3939
JavaxConstraintPrism.PRISM_TYPE,
4040
CrossParamConstraintPrism.PRISM_TYPE,
41-
ValidMethodPrism.PRISM_TYPE
41+
ValidMethodPrism.PRISM_TYPE,
42+
"io.avaje.spi.ServiceProvider"
4243
})
4344
public final class ValidationProcessor extends AbstractProcessor {
4445

@@ -74,7 +75,7 @@ private void readModule() {
7475

7576
@Override
7677
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment round) {
77-
APContext.setProjectModuleElement(annotations, round);
78+
APContext.setProjectModuleElement(annotations, round);
7879
readModule();
7980
getElements(round, AvajeConstraintPrism.PRISM_TYPE).ifPresent(this::writeConstraintAdapters);
8081
getElements(round, JavaxConstraintPrism.PRISM_TYPE).ifPresent(this::writeConstraintAdapters);
@@ -93,6 +94,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
9394
.map(ElementFilter::methodsIn)
9495
.ifPresent(this::writeParamProviderForMethod);
9596
getElements(round, ImportValidPojoPrism.PRISM_TYPE).ifPresent(this::writeAdaptersForImported);
97+
getElements(round, "io.avaje.spi.ServiceProvider").ifPresent(this::registerSPI);
98+
9699
initialiseComponent();
97100
cascadeTypes();
98101
writeComponent(round.processingOver());
@@ -326,4 +329,16 @@ private void writeParamProvider(ExecutableElement typeElement) {
326329
logError("Error writing ValidationAdapter for %s %s", beanReader, e);
327330
}
328331
}
332+
333+
private void registerSPI(Set<? extends Element> beans) {
334+
ElementFilter.typesIn(beans).stream()
335+
.filter(this::isExtension)
336+
.map(TypeElement::getQualifiedName)
337+
.map(Object::toString)
338+
.forEach(ProcessingContext::addValidatorSpi);
339+
}
340+
341+
private boolean isExtension(TypeElement te) {
342+
return APContext.isAssignable(te, "io.avaje.validation.spi.ValidationExtension");
343+
}
329344
}

validator-http-plugin/pom.xml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,6 @@
2020
<optional>true</optional>
2121
</dependency>
2222

23-
<dependency>
24-
<groupId>io.avaje</groupId>
25-
<artifactId>avaje-spi-service</artifactId>
26-
<version>${spi.version}</version>
27-
<optional>true</optional>
28-
</dependency>
29-
3023
<dependency>
3124
<groupId>io.avaje</groupId>
3225
<artifactId>avaje-validator-inject-plugin</artifactId>

validator-http-plugin/src/main/java/io/avaje/validation/http/HttpValidatorProvider.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.avaje.validation.http;
22

33
import io.avaje.inject.BeanScopeBuilder;
4-
import io.avaje.spi.ServiceProvider;
54

65
import java.util.ArrayList;
76
import java.util.Arrays;
@@ -10,7 +9,6 @@
109
/**
1110
* Plugin for avaje inject that provides a default Http Validator instance.
1211
*/
13-
@ServiceProvider
1412
public final class HttpValidatorProvider implements io.avaje.inject.spi.InjectPlugin {
1513

1614
private static final Class<?> VALIDATOR_HTTP_CLASS = avajeHttpOnClasspath();

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
requires transitive io.avaje.validation.plugin;
66
requires transitive io.avaje.http.api;
7-
requires static io.avaje.spi;
87

98
provides io.avaje.inject.spi.InjectExtension with io.avaje.validation.http.HttpValidatorProvider;
109
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.avaje.validation.http.HttpValidatorProvider

validator-inject-plugin/pom.xml

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,6 @@
3535
<scope>test</scope>
3636
</dependency>
3737

38-
<dependency>
39-
<groupId>io.avaje</groupId>
40-
<artifactId>avaje-spi-service</artifactId>
41-
<version>${spi.version}</version>
42-
<optional>true</optional>
43-
</dependency>
44-
4538
<dependency>
4639
<groupId>io.avaje</groupId>
4740
<artifactId>junit</artifactId>

validator-inject-plugin/src/main/java/io/avaje/validation/inject/spi/DefaultValidatorProvider.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@
1111
import io.avaje.inject.aop.AspectProvider;
1212
import io.avaje.inject.spi.GenericType;
1313
import io.avaje.inject.spi.InjectPlugin;
14-
import io.avaje.spi.ServiceProvider;
1514
import io.avaje.validation.ValidMethod;
1615
import io.avaje.validation.Validator;
1716
import io.avaje.validation.adapter.MethodAdapterProvider;
1817
import io.avaje.validation.inject.aspect.AOPMethodValidator;
1918

2019
/** Plugin for avaje inject that provides a default Validator instance. */
21-
@ServiceProvider
2220
public final class DefaultValidatorProvider implements InjectPlugin {
2321

2422
@Override

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
requires transitive io.avaje.validation;
44
requires transitive io.avaje.inject;
55
requires transitive io.avaje.inject.aop;
6-
requires static io.avaje.spi;
76

87
provides io.avaje.inject.spi.InjectExtension with io.avaje.validation.inject.spi.DefaultValidatorProvider;
98
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
io.avaje.validation.inject.spi.DefaultValidatorProvider

0 commit comments

Comments
 (0)