Skip to content

Commit

Permalink
Added a method to walk a subtree of a given PathTree
Browse files Browse the repository at this point in the history
  • Loading branch information
aloubyansky committed Jun 8, 2024
1 parent 9222a8a commit 8caea92
Show file tree
Hide file tree
Showing 15 changed files with 11,003 additions and 280 deletions.
10,705 changes: 10,705 additions & 0 deletions extensions/qute/deployment/log

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import static java.util.function.Predicate.not;
import static java.util.stream.Collectors.toMap;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
Expand Down Expand Up @@ -37,6 +38,7 @@
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import jakarta.inject.Singleton;

Expand Down Expand Up @@ -97,8 +99,6 @@
import io.quarkus.maven.dependency.DependencyFlags;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.panache.common.deployment.PanacheEntityClassesBuildItem;
import io.quarkus.paths.FilteredPathTree;
import io.quarkus.paths.PathFilter;
import io.quarkus.paths.PathTree;
import io.quarkus.qute.CheckedTemplate;
import io.quarkus.qute.Engine;
Expand Down Expand Up @@ -2163,18 +2163,76 @@ private void scanPathTree(PathTree pathTree, TemplateRootsBuildItem templateRoot
BuildProducer<TemplatePathBuildItem> templatePaths,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
QuteConfig config) {
//final boolean isWindows = PropertyUtils.isWindows();
for (String templateRoot : templateRoots) {
pathTree.accept(templateRoot, visit -> {
if (visit != null) {
// if template root is found in this tree then walk over its subtree
scanTemplateRootSubtree(
new FilteredPathTree(pathTree, PathFilter.forIncludes(List.of(templateRoot + "/**"))),
visit.getRelativePath(), watchedPaths, templatePaths, nativeImageResources, config);
// On Windows 'Templates' path may be returned when 'templates' is requested.
// The path filter helps filter out paths such as 'Templates'.
if (/* isWindows && */!containsPath(pathTree, templateRoot)) {
continue;
}
pathTree.walkIfContains(templateRoot, visit -> {
if (Files.isRegularFile(visit.getPath())) {
LOGGER.debugf("Found template: %s", visit.getPath());
// remove templateRoot + /
final String relativePath = visit.getRelativePath();
String templatePath = relativePath.substring(templateRoot.length() + 1);
if (config.templatePathExclude.matcher(templatePath).matches()) {
LOGGER.debugf("Template file excluded: %s", visit.getPath());
return;
}
produceTemplateBuildItems(templatePaths, watchedPaths, nativeImageResources,
relativePath, templatePath, visit.getPath(), config);
}
});
}
}

private static boolean containsPath(PathTree pathTree, String relativePath) {
if (File.separatorChar != '/') {
relativePath = relativePath.replace(File.separatorChar, '/');
}
final String[] pathElements = relativePath.split("\\/");
try (var openTree = pathTree.open()) {
for (var root : openTree.getRoots()) {
if (containsPath(root, pathElements)) {
return true;
}
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return false;
}

private static boolean containsPath(Path root, String[] pathElements) {
var parent = root;
for (String pathElement : pathElements) {
try (Stream<Path> stream = Files.list(parent)) {
var iter = stream.iterator();
Path match = null;
while (iter.hasNext()) {
final Path next = iter.next();
if (pathElement.equals(next.getFileName().toString())) {
if (!Files.isDirectory(next)) {
return false;
}
match = next;
break;
}
}
if (match == null) {
return false;
}
parent = match;
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (Exception e) {
throw e;
}
}
return true;
}

@BuildStep
TemplateFilePathsBuildItem collectTemplateFilePaths(QuteConfig config, List<TemplatePathBuildItem> templatePaths) {
Set<String> filePaths = new HashSet<String>();
Expand Down Expand Up @@ -3382,27 +3440,6 @@ private static void produceTemplateBuildItems(BuildProducer<TemplatePathBuildIte
readTemplateContent(originalPath, config.defaultCharset)));
}

private void scanTemplateRootSubtree(PathTree pathTree, String templateRoot,
BuildProducer<HotDeploymentWatchedFileBuildItem> watchedPaths,
BuildProducer<TemplatePathBuildItem> templatePaths,
BuildProducer<NativeImageResourceBuildItem> nativeImageResources,
QuteConfig config) {
pathTree.walk(visit -> {
if (Files.isRegularFile(visit.getPath())) {
LOGGER.debugf("Found template: %s", visit.getPath());
// remove templateRoot + /
final String relativePath = visit.getRelativePath();
String templatePath = relativePath.substring(templateRoot.length() + 1);
if (config.templatePathExclude.matcher(templatePath).matches()) {
LOGGER.debugf("Template file excluded: %s", visit.getPath());
return;
}
produceTemplateBuildItems(templatePaths, watchedPaths, nativeImageResources,
relativePath, templatePath, visit.getPath(), config);
}
});
}

private static boolean isExcluded(TypeCheck check, Iterable<Predicate<TypeCheck>> excludes) {
for (Predicate<TypeCheck> exclude : excludes) {
if (exclude.test(check)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import io.quarkus.deployment.builditem.LaunchModeBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
import io.quarkus.paths.FilteredPathTree;
import io.quarkus.paths.PathFilter;
import io.quarkus.paths.PathVisitor;
import io.quarkus.vertx.core.deployment.CoreVertxBuildItem;
import io.quarkus.vertx.http.deployment.spi.AdditionalStaticResourceBuildItem;
Expand Down Expand Up @@ -86,7 +84,7 @@ public void nativeImageResource(Optional<StaticResourcesBuildItem> staticResourc
final Set<String> collectedDirs = new HashSet<>();
visitRuntimeMetaInfResources(visit -> {
if (Files.isDirectory(visit.getPath())) {
final String relativePath = visit.getRelativePath("/");
final String relativePath = visit.getRelativePath();
if (collectedDirs.add(relativePath)) {
producer.produce(new NativeImageResourceBuildItem(relativePath));
}
Expand All @@ -105,7 +103,7 @@ private Set<StaticResourcesBuildItem.Entry> getClasspathResources() {
visitRuntimeMetaInfResources(visit -> {
if (!Files.isDirectory(visit.getPath())) {
knownPaths.add(new StaticResourcesBuildItem.Entry(
visit.getRelativePath("/").substring(StaticResourcesRecorder.META_INF_RESOURCES.length()),
visit.getRelativePath().substring(StaticResourcesRecorder.META_INF_RESOURCES.length()),
false));
}
});
Expand All @@ -121,13 +119,10 @@ private static void visitRuntimeMetaInfResources(PathVisitor visitor) {
final List<ClassPathElement> elements = QuarkusClassLoader.getElements(StaticResourcesRecorder.META_INF_RESOURCES,
false);
if (!elements.isEmpty()) {
final PathFilter filter = PathFilter.forIncludes(List.of(
StaticResourcesRecorder.META_INF_RESOURCES + "/**",
StaticResourcesRecorder.META_INF_RESOURCES));
for (var element : elements) {
if (element.isRuntime()) {
element.apply(tree -> {
new FilteredPathTree(tree, filter).walk(visitor);
tree.walkIfContains(StaticResourcesRecorder.META_INF_RESOURCES, visitor);
return null;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,25 @@ public Collection<Path> getRoots() {
public void walk(PathVisitor visitor) {
try (FileSystem fs = openFs()) {
final Path dir = fs.getPath("/");
PathTreeVisit.walk(archive, dir, pathFilter, getMultiReleaseMapping(), visitor);
PathTreeVisit.walk(archive, dir, dir, pathFilter, getMultiReleaseMapping(), visitor);
} catch (IOException e) {
throw new UncheckedIOException("Failed to read " + archive, e);
}
}

@Override
public void walkIfContains(String relativePath, PathVisitor visitor) {
ensureResourcePath(relativePath);
if (!PathFilter.isVisible(pathFilter, relativePath)) {
return;
}
try (FileSystem fs = openFs()) {
for (Path root : fs.getRootDirectories()) {
final Path walkDir = root.resolve(relativePath);
if (Files.exists(walkDir)) {
PathTreeVisit.walk(archive, root, walkDir, pathFilter, getMultiReleaseMapping(), visitor);
}
}
} catch (IOException e) {
throw new UncheckedIOException("Failed to read " + archive, e);
}
Expand Down Expand Up @@ -287,6 +305,17 @@ public void walk(PathVisitor visitor) {
}
}

@Override
public void walkIfContains(String relativePath, PathVisitor visitor) {
lock.readLock().lock();
try {
ensureOpen();
super.walkIfContains(relativePath, visitor);
} finally {
lock.readLock().unlock();
}
}

@Override
public boolean contains(String relativePath) {
lock.readLock().lock();
Expand Down
Loading

0 comments on commit 8caea92

Please sign in to comment.