|
25 | 25 |
|
26 | 26 | public class ProcessingContext {
|
27 | 27 |
|
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 | + } |
41 | 74 | }
|
42 | 75 |
|
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); |
49 | 80 |
|
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; |
53 | 83 | }
|
| 84 | + CTX.set(newCTX); |
| 85 | + } |
54 | 86 |
|
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); |
72 | 89 | }
|
73 | 90 |
|
74 | 91 | private static boolean isTypeAvailable(String canonicalName) {
|
75 | 92 | return null != typeElement(canonicalName);
|
76 | 93 | }
|
77 | 94 |
|
78 | 95 | public static TypeElement typeElement(String canonicalName) {
|
79 |
| - return ELEMENTS.get().getTypeElement(canonicalName); |
| 96 | + return CTX.get().elementUtils.getTypeElement(canonicalName); |
80 | 97 | }
|
81 | 98 |
|
82 | 99 | public static boolean isOpenApiAvailable() {
|
83 |
| - return OPENAPI_AVAILABLE.get(); |
| 100 | + return CTX.get().openApiAvailable; |
84 | 101 | }
|
85 | 102 |
|
86 | 103 | public static boolean useJavax() {
|
87 |
| - return USE_JAVAX.get(); |
| 104 | + return CTX.get().useJavax; |
88 | 105 | }
|
89 | 106 |
|
90 | 107 | public static boolean useComponent() {
|
91 |
| - return USE_COMPONENT.get(); |
| 108 | + return CTX.get().useComponent; |
92 | 109 | }
|
93 | 110 |
|
94 | 111 | 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); |
96 | 113 | }
|
97 | 114 |
|
98 |
| - /** |
99 |
| - * Create a file writer for the given class name. |
100 |
| - */ |
| 115 | + /** Create a file writer for the given class name. */ |
101 | 116 | 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); |
103 | 118 | }
|
104 | 119 |
|
105 |
| - /** |
106 |
| - * Create a file writer for the META-INF services file. |
107 |
| - */ |
| 120 | + /** Create a file writer for the META-INF services file. */ |
108 | 121 | 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); |
110 | 123 | }
|
111 | 124 |
|
112 | 125 | public static String docComment(Element param) {
|
113 |
| - return ELEMENTS.get().getDocComment(param); |
| 126 | + return CTX.get().elementUtils.getDocComment(param); |
114 | 127 | }
|
115 | 128 |
|
116 | 129 | public static DocContext doc() {
|
117 |
| - return DOC_CONTEXT.get(); |
| 130 | + return CTX.get().docContext; |
118 | 131 | }
|
119 | 132 |
|
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); |
122 | 135 | }
|
123 | 136 |
|
124 | 137 | public static TypeMirror asMemberOf(DeclaredType declaredType, Element element) {
|
125 |
| - return TYPES.get().asMemberOf(declaredType, element); |
| 138 | + return CTX.get().typeUtils.asMemberOf(declaredType, element); |
126 | 139 | }
|
127 | 140 |
|
128 | 141 | public static List<ExecutableElement> superMethods(Element element, String methodName) {
|
129 |
| - final Types types = TYPES.get(); |
| 142 | + final Types types = CTX.get().typeUtils; |
130 | 143 | 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()); |
145 | 158 | }
|
146 | 159 |
|
147 | 160 | public static PlatformAdapter platform() {
|
148 |
| - return READ_ADAPTER.get(); |
| 161 | + return CTX.get().readAdapter; |
149 | 162 | }
|
150 | 163 |
|
151 | 164 | public static void setPlatform(PlatformAdapter platform) {
|
152 |
| - READ_ADAPTER.set(platform); |
| 165 | + CTX.get().readAdapter = (platform); |
153 | 166 | }
|
154 | 167 |
|
155 | 168 | public static String diAnnotation() {
|
156 |
| - return DI_ANNOTATION.get(); |
| 169 | + return CTX.get().diAnnotation; |
157 | 170 | }
|
158 | 171 | }
|
0 commit comments