|
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