11package io .toolisticon .cute ;
22
3- import javax .tools .FileObject ;
4- import javax .tools .ForwardingJavaFileManager ;
5- import javax .tools .JavaFileManager ;
6- import javax .tools .JavaFileObject ;
7- import javax .tools .SimpleJavaFileObject ;
8- import javax .tools .StandardJavaFileManager ;
93import java .io .ByteArrayInputStream ;
104import java .io .ByteArrayOutputStream ;
115import java .io .IOException ;
2216import java .util .List ;
2317import java .util .Map ;
2418
19+ import javax .tools .FileObject ;
20+ import javax .tools .ForwardingJavaFileManager ;
21+ import javax .tools .JavaFileManager ;
22+ import javax .tools .JavaFileObject ;
23+ import javax .tools .SimpleJavaFileObject ;
24+ import javax .tools .StandardJavaFileManager ;
25+ import javax .tools .StandardLocation ;
26+
27+ import io .toolisticon .cute .CuteApi .ResourceFileBB ;
28+
2529/**
2630 * Forwarding file manager to be able to test for generated sources and resources
2731 */
2832class CompileTestFileManager extends ForwardingJavaFileManager <StandardJavaFileManager > {
2933
3034
35+ /**
36+ * The file object cache that is used to store generated classes and resources.
37+ * @param <T> The type of cached file objects, must be either FileObject or JavaFileObject
38+ */
3139 public static class FileObjectCache <T extends FileObject > {
3240
3341 final Map <URI , T > fileObjectCache = new HashMap <>();
@@ -54,15 +62,46 @@ public boolean isEmpty() {
5462 }
5563
5664
65+ }
66+
67+ /**
68+ * This internal class is used to provide resources from class path via a custom package.
69+ * Internally this works like an alias.
70+ * It hides any pre-existing resources with uri.
71+ */
72+ public static class ProvidedResourceFilesCache {
73+
74+
75+ final Map <URI , FileObject > resourcesMap = new HashMap <>();
76+
77+ ProvidedResourceFilesCache (List <ResourceFileBB > resourceFiles ) {
78+
79+ if (resourceFiles != null ) {
80+ resourceFiles .stream ().filter (e -> e .getRelativeName () != null ).forEach ( e -> resourcesMap .put (uriForFileObject (StandardLocation .CLASS_PATH , e .targetPackageName (), e .getRelativeName ()), FileObjectUtils .forPassedInResource (e )));
81+ }
82+
83+ }
84+
85+ FileObject get (String packageName , String relativeName ) {
86+ URI uri = uriForFileObject (StandardLocation .CLASS_PATH , packageName ,relativeName );
87+ return this .resourcesMap .get (uri );
88+ }
89+
90+
91+
5792 }
5893
5994
6095 private final FileObjectCache <InMemoryOutputJavaFileObject > generatedJavaFileObjectCache = new FileObjectCache <>();
6196 private final FileObjectCache <InMemoryOutputFileObject > generatedFileObjectCache = new FileObjectCache <>();
97+ private final ProvidedResourceFilesCache providedResourceFilesCache ;
6298
6399
64- public CompileTestFileManager (StandardJavaFileManager standardJavaFileManager ) {
100+ public CompileTestFileManager (StandardJavaFileManager standardJavaFileManager , List < CuteApi . ResourceFileBB > resourceFiles ) {
65101 super (standardJavaFileManager );
102+
103+ // configure cache for resource files
104+ providedResourceFilesCache = new ProvidedResourceFilesCache (resourceFiles );
66105
67106 }
68107
@@ -124,7 +163,18 @@ public FileObject getFileForInput(Location location, String packageName, String
124163 } else {
125164 throw new IllegalArgumentException (Constants .Messages .IAE_CANNOT_FIND_FILEOBJECT .produceMessage (uri .toString ()));
126165 }
166+ } else if (StandardLocation .CLASS_PATH .equals (location )) {
167+
168+ // Try to get it from provided resource file cache
169+ FileObject providedResource = this .providedResourceFilesCache .get (packageName , relativeName );
170+
171+ if (providedResource != null ) {
172+ return providedResource ;
173+ }
174+
127175 }
176+
177+ // use standard manager if file haven't been found so far
128178 return super .getFileForInput (location , packageName , relativeName );
129179 }
130180
@@ -138,8 +188,17 @@ public FileObject getFileForInput(Location location, String packageName, String
138188 * @return true if JavaFileObject exists, otherwise false
139189 */
140190 public boolean existsExpectedJavaFileObject (JavaFileManager .Location location , String className , JavaFileObject .Kind kind ) {
141-
142- return this .generatedJavaFileObjectCache .contains (uriForJavaFileObject (location , className , kind ));
191+
192+ if (location .isOutputLocation ()) {
193+ return this .generatedJavaFileObjectCache .contains (uriForJavaFileObject (location , className , kind ));
194+ }
195+
196+ try {
197+ return super .getJavaFileForInput (location , className , kind ) != null ;
198+ } catch (IOException e ) {
199+ throw new IllegalStateException ("Something went wrong while accessing the default FileManager" , e );
200+ }
201+
143202
144203 }
145204
@@ -152,10 +211,24 @@ public boolean existsExpectedJavaFileObject(JavaFileManager.Location location, S
152211 * @return true if FileObject exists, otherwise false
153212 */
154213 public boolean existsExpectedFileObject (JavaFileManager .Location location , String packageName , String relativeName ) {
155-
156- return this .generatedFileObjectCache .contains (uriForFileObject (location , packageName , relativeName ));
157-
158-
214+
215+ // return true if file could be found in resource cache, otherwise check regular file manager
216+ if (StandardLocation .CLASS_PATH .equals (location ) && this .providedResourceFilesCache .get (packageName , relativeName ) != null ) {
217+ return true ;
218+ }
219+
220+ // otherwise check the generated file object cache
221+ if (location .isOutputLocation ()) {
222+ return this .generatedFileObjectCache .contains (uriForFileObject (location , packageName , relativeName ));
223+ }
224+
225+ // use standard file manager for input files
226+ try {
227+ return super .getFileForInput (location , packageName , relativeName ) != null ;
228+ } catch (IOException e ) {
229+ throw new IllegalStateException ("Something went wrong while accessing the default FileManager" , e );
230+ }
231+
159232 }
160233
161234
@@ -166,7 +239,7 @@ interface OutputStreamCallback {
166239 }
167240
168241
169- private static URI uriForFileObject (Location location , String packageName , String relativeName ) {
242+ static URI uriForFileObject (Location location , String packageName , String relativeName ) {
170243 StringBuilder uri = new StringBuilder ("mem://" ).append (location .getName ()).append ('/' );
171244 if (!packageName .isEmpty ()) {
172245 uri .append (packageName .replace ('.' , '/' )).append ('/' );
@@ -304,4 +377,5 @@ public void write(byte[] b) throws IOException {
304377 outputStreamCallback .setContent (this .toByteArray ());
305378 }
306379 }
380+
307381}
0 commit comments