Skip to content

Commit 6aaa596

Browse files
authored
Single ThreadLocal Context (#185)
* Single ThreadLocal * there we go * should work now
1 parent be6e978 commit 6aaa596

File tree

1 file changed

+88
-75
lines changed

1 file changed

+88
-75
lines changed

http-generator-core/src/main/java/io/avaje/http/generator/core/ProcessingContext.java

Lines changed: 88 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -25,134 +25,147 @@
2525

2626
public class ProcessingContext {
2727

28-
private static final ThreadLocal<PlatformAdapter> READ_ADAPTER = new ThreadLocal<>();
29-
private static final ThreadLocal<Messager> MESSAGER = new ThreadLocal<>();
30-
private static final ThreadLocal<Filer> FILER = new ThreadLocal<>();
31-
private static final ThreadLocal<Elements> ELEMENTS = new ThreadLocal<>();
32-
private static final ThreadLocal<Types> TYPES = new ThreadLocal<>();
33-
private static final ThreadLocal<Boolean> OPENAPI_AVAILABLE = ThreadLocal.withInitial(() -> false);
34-
private static final ThreadLocal<DocContext> DOC_CONTEXT = new ThreadLocal<>();
35-
private static final ThreadLocal<Boolean> USE_COMPONENT = ThreadLocal.withInitial(() -> false);
36-
private static final ThreadLocal<Boolean> USE_JAVAX = ThreadLocal.withInitial(() -> false);
37-
private static final ThreadLocal<String> DI_ANNOTATION = new ThreadLocal<>();
38-
39-
public static void init(ProcessingEnvironment env, PlatformAdapter adapter) {
40-
init(env, adapter, true);
28+
private static final ThreadLocal<Ctx> CTX = new ThreadLocal<>();
29+
30+
private ProcessingContext() {}
31+
32+
static final class Ctx {
33+
private PlatformAdapter readAdapter;
34+
private final Messager messager;
35+
private final Filer filer;
36+
private final Elements elementUtils;
37+
private final Types typeUtils;
38+
private boolean openApiAvailable;
39+
private DocContext docContext;
40+
private final boolean useComponent;
41+
private final boolean useJavax;
42+
private final String diAnnotation;
43+
44+
public Ctx(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) {
45+
readAdapter = adapter;
46+
messager = env.getMessager();
47+
filer = env.getFiler();
48+
elementUtils = env.getElementUtils();
49+
typeUtils = env.getTypeUtils();
50+
51+
if (generateOpenAPI) {
52+
openApiAvailable = elementUtils.getTypeElement(Constants.OPENAPIDEFINITION) != null;
53+
docContext = new DocContext(env, openApiAvailable);
54+
}
55+
56+
final var options = env.getOptions();
57+
final var singletonOverride = options.get("useSingleton");
58+
if (singletonOverride != null) {
59+
useComponent = (!Boolean.parseBoolean(singletonOverride));
60+
} else {
61+
useComponent = elementUtils.getTypeElement(Constants.COMPONENT) != null;
62+
}
63+
diAnnotation = (useComponent ? "@Component" : "@Singleton");
64+
65+
final var javax = elementUtils.getTypeElement(Constants.SINGLETON_JAVAX) != null;
66+
final var jakarta = elementUtils.getTypeElement(Constants.SINGLETON_JAKARTA) != null;
67+
final var override = env.getOptions().get("useJavax");
68+
if (override != null || (javax && jakarta)) {
69+
useJavax = Boolean.parseBoolean(override);
70+
} else {
71+
useJavax = (javax);
72+
}
73+
}
4174
}
4275

43-
public static void init(ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) {
44-
READ_ADAPTER.set(adapter);
45-
MESSAGER.set(env.getMessager());
46-
FILER.set(env.getFiler());
47-
ELEMENTS.set(env.getElementUtils());
48-
TYPES.set(env.getTypeUtils());
76+
public static void init(
77+
ProcessingEnvironment env, PlatformAdapter adapter, boolean generateOpenAPI) {
78+
final var oldCtx = CTX.get();
79+
final var newCTX = new Ctx(env, adapter, generateOpenAPI);
4980

50-
if (generateOpenAPI) {
51-
OPENAPI_AVAILABLE.set(isTypeAvailable(Constants.OPENAPIDEFINITION));
52-
DOC_CONTEXT.set(new DocContext(env, OPENAPI_AVAILABLE.get()));
81+
if (oldCtx != null && newCTX.docContext == null) {
82+
newCTX.docContext = oldCtx.docContext;
5383
}
84+
CTX.set(newCTX);
85+
}
5486

55-
final var options = env.getOptions();
56-
final var singletonOverride = options.get("useSingleton");
57-
if (singletonOverride != null) {
58-
USE_COMPONENT.set(!Boolean.parseBoolean(singletonOverride));
59-
} else {
60-
USE_COMPONENT.set(isTypeAvailable(Constants.COMPONENT));
61-
}
62-
DI_ANNOTATION.set(USE_COMPONENT.get() ? "@Component" : "@Singleton");
63-
64-
final var javax = isTypeAvailable(Constants.SINGLETON_JAVAX);
65-
final var jakarta = isTypeAvailable(Constants.SINGLETON_JAKARTA);
66-
final var override = env.getOptions().get("useJavax");
67-
if (override != null || (javax && jakarta)) {
68-
USE_JAVAX.set(Boolean.parseBoolean(override));
69-
} else {
70-
USE_JAVAX.set(javax);
71-
}
87+
public static void init(ProcessingEnvironment env, PlatformAdapter adapter) {
88+
init(env, adapter, true);
7289
}
7390

7491
private static boolean isTypeAvailable(String canonicalName) {
7592
return null != typeElement(canonicalName);
7693
}
7794

7895
public static TypeElement typeElement(String canonicalName) {
79-
return ELEMENTS.get().getTypeElement(canonicalName);
96+
return CTX.get().elementUtils.getTypeElement(canonicalName);
8097
}
8198

8299
public static boolean isOpenApiAvailable() {
83-
return OPENAPI_AVAILABLE.get();
100+
return CTX.get().openApiAvailable;
84101
}
85102

86103
public static boolean useJavax() {
87-
return USE_JAVAX.get();
104+
return CTX.get().useJavax;
88105
}
89106

90107
public static boolean useComponent() {
91-
return USE_COMPONENT.get();
108+
return CTX.get().useComponent;
92109
}
93110

94111
public static void logError(Element e, String msg, Object... args) {
95-
MESSAGER.get().printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e);
112+
CTX.get().messager.printMessage(Diagnostic.Kind.ERROR, String.format(msg, args), e);
96113
}
97114

98-
/**
99-
* Create a file writer for the given class name.
100-
*/
115+
/** Create a file writer for the given class name. */
101116
public static JavaFileObject createWriter(String cls, Element origin) throws IOException {
102-
return FILER.get().createSourceFile(cls, origin);
117+
return CTX.get().filer.createSourceFile(cls, origin);
103118
}
104119

105-
/**
106-
* Create a file writer for the META-INF services file.
107-
*/
120+
/** Create a file writer for the META-INF services file. */
108121
public static FileObject createMetaInfWriter(String target) throws IOException {
109-
return FILER.get().createResource(StandardLocation.CLASS_OUTPUT, "", target);
122+
return CTX.get().filer.createResource(StandardLocation.CLASS_OUTPUT, "", target);
110123
}
111124

112125
public static String docComment(Element param) {
113-
return ELEMENTS.get().getDocComment(param);
126+
return CTX.get().elementUtils.getDocComment(param);
114127
}
115128

116129
public static DocContext doc() {
117-
return DOC_CONTEXT.get();
130+
return CTX.get().docContext;
118131
}
119132

120-
public static Element asElement(TypeMirror typeMirror) {
121-
return TYPES.get().asElement(typeMirror);
133+
public static TypeElement asElement(TypeMirror typeMirror) {
134+
return (TypeElement) CTX.get().typeUtils.asElement(typeMirror);
122135
}
123136

124137
public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) {
125-
return TYPES.get().asMemberOf(declaredType, element);
138+
return CTX.get().typeUtils.asMemberOf(declaredType, element);
126139
}
127140

128141
public static List<ExecutableElement> superMethods(Element element, String methodName) {
129-
final Types types = TYPES.get();
142+
final Types types = CTX.get().typeUtils;
130143
return types.directSupertypes(element.asType()).stream()
131-
.filter(type -> !type.toString().contains("java.lang.Object"))
132-
.map(
133-
superType -> {
134-
final var superClass = (TypeElement) types.asElement(superType);
135-
for (final ExecutableElement method :
136-
ElementFilter.methodsIn(ELEMENTS.get().getAllMembers(superClass))) {
137-
if (method.getSimpleName().contentEquals(methodName)) {
138-
return method;
139-
}
140-
}
141-
return null;
142-
})
143-
.filter(Objects::nonNull)
144-
.collect(Collectors.toList());
144+
.filter(type -> !type.toString().contains("java.lang.Object"))
145+
.map(
146+
superType -> {
147+
final var superClass = (TypeElement) types.asElement(superType);
148+
for (final ExecutableElement method :
149+
ElementFilter.methodsIn(CTX.get().elementUtils.getAllMembers(superClass))) {
150+
if (method.getSimpleName().contentEquals(methodName)) {
151+
return method;
152+
}
153+
}
154+
return null;
155+
})
156+
.filter(Objects::nonNull)
157+
.collect(Collectors.toList());
145158
}
146159

147160
public static PlatformAdapter platform() {
148-
return READ_ADAPTER.get();
161+
return CTX.get().readAdapter;
149162
}
150163

151164
public static void setPlatform(PlatformAdapter platform) {
152-
READ_ADAPTER.set(platform);
165+
CTX.get().readAdapter = (platform);
153166
}
154167

155168
public static String diAnnotation() {
156-
return DI_ANNOTATION.get();
169+
return CTX.get().diAnnotation;
157170
}
158171
}

0 commit comments

Comments
 (0)