38
38
import java .util .function .Predicate ;
39
39
import java .util .regex .Pattern ;
40
40
import java .util .stream .Collectors ;
41
- import java .util .stream .Stream ;
42
41
43
42
import jakarta .inject .Singleton ;
44
43
93
92
import io .quarkus .deployment .builditem .nativeimage .ReflectiveClassBuildItem ;
94
93
import io .quarkus .deployment .pkg .NativeConfig ;
95
94
import io .quarkus .deployment .pkg .builditem .CurateOutcomeBuildItem ;
96
- import io .quarkus .fs .util .ZipUtils ;
97
95
import io .quarkus .gizmo .ClassOutput ;
98
96
import io .quarkus .gizmo .MethodDescriptor ;
99
- import io .quarkus .maven .dependency .Dependency ;
97
+ import io .quarkus .maven .dependency .ArtifactKey ;
98
+ import io .quarkus .maven .dependency .DependencyFlags ;
100
99
import io .quarkus .maven .dependency .ResolvedDependency ;
101
100
import io .quarkus .panache .common .deployment .PanacheEntityClassesBuildItem ;
101
+ import io .quarkus .paths .FilteredPathTree ;
102
+ import io .quarkus .paths .PathFilter ;
103
+ import io .quarkus .paths .PathTree ;
102
104
import io .quarkus .qute .CheckedTemplate ;
103
105
import io .quarkus .qute .Engine ;
104
106
import io .quarkus .qute .EngineBuilder ;
@@ -2124,9 +2126,6 @@ void collectTemplates(ApplicationArchivesBuildItem applicationArchives,
2124
2126
QuteConfig config ,
2125
2127
TemplateRootsBuildItem templateRoots )
2126
2128
throws IOException {
2127
- Set <ApplicationArchive > allApplicationArchives = applicationArchives .getAllApplicationArchives ();
2128
- List <ResolvedDependency > extensionArtifacts = curateOutcome .getApplicationModel ().getDependencies ().stream ()
2129
- .filter (Dependency ::isRuntimeExtensionArtifact ).collect (Collectors .toList ());
2130
2129
2131
2130
// Make sure the new templates are watched as well
2132
2131
watchedPaths .produce (HotDeploymentWatchedFileBuildItem .builder ().setLocationPredicate (new Predicate <String >() {
@@ -2141,80 +2140,39 @@ public boolean test(String path) {
2141
2140
}
2142
2141
}).build ());
2143
2142
2144
- for (ResolvedDependency artifact : extensionArtifacts ) {
2145
- if (isApplicationArchive (artifact , allApplicationArchives )) {
2146
- // Skip extension archives that are also application archives
2147
- continue ;
2148
- }
2149
- for (Path resolvedPath : artifact .getResolvedPaths ()) {
2150
- if (Files .isDirectory (resolvedPath )) {
2151
- scanRootPath (resolvedPath , config , templateRoots , watchedPaths , templatePaths ,
2152
- nativeImageResources );
2153
- } else {
2154
- try (FileSystem artifactFs = ZipUtils .newFileSystem (resolvedPath )) {
2155
- // Iterate over template roots, such as "templates", and collect the included templates
2156
- for (String templateRoot : templateRoots ) {
2157
- Path artifactBasePath = artifactFs .getPath (templateRoot );
2158
- if (Files .exists (artifactBasePath )) {
2159
- LOGGER .debugf ("Found template root in extension artifact: %s" , resolvedPath );
2160
- scanDirectory (artifactBasePath , artifactBasePath , templateRoot + "/" , watchedPaths ,
2161
- templatePaths ,
2162
- nativeImageResources ,
2163
- config );
2164
- }
2165
- }
2166
- } catch (IOException e ) {
2167
- LOGGER .warnf (e , "Unable to create the file system from the path: %s" , resolvedPath );
2168
- }
2169
- }
2143
+ final Set <ApplicationArchive > allApplicationArchives = applicationArchives .getAllApplicationArchives ();
2144
+ final Set <ArtifactKey > appArtifactKeys = new HashSet <>(allApplicationArchives .size ());
2145
+ for (var archive : allApplicationArchives ) {
2146
+ appArtifactKeys .add (archive .getKey ());
2147
+ }
2148
+ for (ResolvedDependency artifact : curateOutcome .getApplicationModel ()
2149
+ .getDependencies (DependencyFlags .RUNTIME_EXTENSION_ARTIFACT )) {
2150
+ // Skip extension archives that are also application archives
2151
+ if (!appArtifactKeys .contains (artifact .getKey ())) {
2152
+ scanPathTree (artifact .getContentTree (), templateRoots , watchedPaths , templatePaths , nativeImageResources ,
2153
+ config );
2170
2154
}
2171
2155
}
2172
2156
for (ApplicationArchive archive : allApplicationArchives ) {
2173
- archive .accept (tree -> {
2174
- for (Path root : tree .getRoots ()) {
2175
- // Note that we cannot use ApplicationArchive.getChildPath(String) here because we would not be able to detect
2176
- // a wrong directory name on case-insensitive file systems
2177
- scanRootPath (root , config , templateRoots , watchedPaths , templatePaths , nativeImageResources );
2178
- }
2179
- });
2157
+ archive .accept (
2158
+ tree -> scanPathTree (tree , templateRoots , watchedPaths , templatePaths , nativeImageResources , config ));
2180
2159
}
2181
2160
}
2182
2161
2183
- private void scanRootPath ( Path rootPath , QuteConfig config , TemplateRootsBuildItem templateRoots ,
2162
+ private void scanPathTree ( PathTree pathTree , TemplateRootsBuildItem templateRoots ,
2184
2163
BuildProducer <HotDeploymentWatchedFileBuildItem > watchedPaths ,
2185
2164
BuildProducer <TemplatePathBuildItem > templatePaths ,
2186
- BuildProducer <NativeImageResourceBuildItem > nativeImageResources ) {
2187
- scanRootPath (rootPath , rootPath , config , templateRoots , watchedPaths , templatePaths , nativeImageResources );
2188
- }
2189
-
2190
- private void scanRootPath (Path rootPath , Path path , QuteConfig config , TemplateRootsBuildItem templateRoots ,
2191
- BuildProducer <HotDeploymentWatchedFileBuildItem > watchedPaths ,
2192
- BuildProducer <TemplatePathBuildItem > templatePaths ,
2193
- BuildProducer <NativeImageResourceBuildItem > nativeImageResources ) {
2194
- if (!Files .isDirectory (path )) {
2195
- return ;
2196
- }
2197
- try (Stream <Path > paths = Files .list (path )) {
2198
- for (Path file : paths .collect (Collectors .toList ())) {
2199
- if (Files .isDirectory (file )) {
2200
- // Iterate over the directories in the root
2201
- // "/io", "/META-INF", "/templates", "/web", etc.
2202
- Path relativePath = rootPath .relativize (file );
2203
- if (templateRoots .isRoot (relativePath )) {
2204
- LOGGER .debugf ("Found templates root dir: %s" , file );
2205
- // The base path is an OS-specific template root path relative to the scanned root path
2206
- String basePath = relativePath .toString () + relativePath .getFileSystem ().getSeparator ();
2207
- scanDirectory (file , file , basePath , watchedPaths , templatePaths ,
2208
- nativeImageResources ,
2209
- config );
2210
- } else if (templateRoots .maybeRoot (relativePath )) {
2211
- // Scan the path recursively because the template root may be nested, for example "/web/public"
2212
- scanRootPath (rootPath , file , config , templateRoots , watchedPaths , templatePaths , nativeImageResources );
2213
- }
2165
+ BuildProducer <NativeImageResourceBuildItem > nativeImageResources ,
2166
+ QuteConfig config ) {
2167
+ for (String templateRoot : templateRoots ) {
2168
+ pathTree .accept (templateRoot , visit -> {
2169
+ if (visit != null ) {
2170
+ // if template root is found in this tree then walk over its subtree
2171
+ scanTemplateRootSubtree (
2172
+ new FilteredPathTree (pathTree , PathFilter .forIncludes (List .of (templateRoot + "/**" ))),
2173
+ visit .getPath (), watchedPaths , templatePaths , nativeImageResources , config );
2214
2174
}
2215
- }
2216
- } catch (IOException e ) {
2217
- throw new UncheckedIOException (e );
2175
+ });
2218
2176
}
2219
2177
}
2220
2178
@@ -3427,55 +3385,24 @@ private static void produceTemplateBuildItems(BuildProducer<TemplatePathBuildIte
3427
3385
readTemplateContent (originalPath , config .defaultCharset )));
3428
3386
}
3429
3387
3430
- /**
3431
- *
3432
- * @param root
3433
- * @param directory
3434
- * @param basePath OS-specific template root path relative to the scanned root path, e.g. {@code templates/}
3435
- * @param watchedPaths
3436
- * @param templatePaths
3437
- * @param nativeImageResources
3438
- * @param config
3439
- * @throws IOException
3440
- */
3441
- private void scanDirectory (Path root , Path directory , String basePath ,
3388
+ private void scanTemplateRootSubtree (PathTree pathTree , Path templateRoot ,
3442
3389
BuildProducer <HotDeploymentWatchedFileBuildItem > watchedPaths ,
3443
3390
BuildProducer <TemplatePathBuildItem > templatePaths ,
3444
3391
BuildProducer <NativeImageResourceBuildItem > nativeImageResources ,
3445
- QuteConfig config )
3446
- throws IOException {
3447
- try (Stream <Path > files = Files .list (directory )) {
3448
- Iterator <Path > iter = files .iterator ();
3449
- while (iter .hasNext ()) {
3450
- Path filePath = iter .next ();
3451
- /*
3452
- * Fix for https://github.com/quarkusio/quarkus/issues/25751 where running tests in Eclipse
3453
- * sometimes produces `/templates/tags` (absolute) files listed for `templates` (relative)
3454
- * directories, so we work around this
3455
- */
3456
- if (!directory .isAbsolute ()
3457
- && filePath .isAbsolute ()
3458
- && filePath .getRoot () != null ) {
3459
- filePath = filePath .getRoot ().relativize (filePath );
3460
- }
3461
- if (Files .isRegularFile (filePath )) {
3462
- LOGGER .debugf ("Found template: %s" , filePath );
3463
- Path relativePath = root .relativize (filePath );
3464
- String templatePath = toOsAgnosticPath (relativePath );
3465
- if (config .templatePathExclude .matcher (templatePath ).matches ()) {
3466
- LOGGER .debugf ("Template file excluded: %s" , filePath );
3467
- continue ;
3468
- }
3469
- produceTemplateBuildItems (templatePaths , watchedPaths , nativeImageResources ,
3470
- basePath + relativePath .toString (),
3471
- templatePath ,
3472
- filePath , config );
3473
- } else if (Files .isDirectory (filePath )) {
3474
- LOGGER .debugf ("Scan directory: %s" , filePath );
3475
- scanDirectory (root , filePath , basePath , watchedPaths , templatePaths , nativeImageResources , config );
3476
- }
3392
+ QuteConfig config ) {
3393
+ pathTree .walk (visit -> {
3394
+ if (Files .isRegularFile (visit .getPath ())) {
3395
+ LOGGER .debugf ("Found template: %s" , visit .getPath ());
3396
+ String templatePath = toOsAgnosticPath (templateRoot .relativize (visit .getPath ()));
3397
+ if (config .templatePathExclude .matcher (templatePath ).matches ()) {
3398
+ LOGGER .debugf ("Template file excluded: %s" , visit .getPath ());
3399
+ return ;
3400
+ }
3401
+ produceTemplateBuildItems (templatePaths , watchedPaths , nativeImageResources ,
3402
+ visit .getRelativePath (visit .getPath ().getFileSystem ().getSeparator ()),
3403
+ templatePath , visit .getPath (), config );
3477
3404
}
3478
- }
3405
+ });
3479
3406
}
3480
3407
3481
3408
private static String toOsAgnosticPath (String path , FileSystem fs ) {
@@ -3518,19 +3445,6 @@ private void checkDuplicatePaths(List<TemplatePathBuildItem> templatePaths) {
3518
3445
}
3519
3446
}
3520
3447
3521
- private boolean isApplicationArchive (ResolvedDependency dependency , Set <ApplicationArchive > applicationArchives ) {
3522
- for (ApplicationArchive archive : applicationArchives ) {
3523
- if (archive .getKey () == null ) {
3524
- continue ;
3525
- }
3526
- if (dependency .getGroupId ().equals (archive .getKey ().getGroupId ())
3527
- && dependency .getArtifactId ().equals (archive .getKey ().getArtifactId ())) {
3528
- return true ;
3529
- }
3530
- }
3531
- return false ;
3532
- }
3533
-
3534
3448
static String readTemplateContent (Path path , Charset defaultCharset ) {
3535
3449
try {
3536
3450
return Files .readString (path , defaultCharset );
0 commit comments