001/* 002 * JDrupes Builder 003 * Copyright (C) 2025 Michael N. Lipp 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <https://www.gnu.org/licenses/>. 017 */ 018 019package org.jdrupes.builder.java; 020 021import java.io.File; 022import java.nio.file.Path; 023import java.util.stream.Stream; 024import org.jdrupes.builder.api.FileTree; 025import org.jdrupes.builder.api.Project; 026import org.jdrupes.builder.api.Resource; 027import org.jdrupes.builder.api.ResourceRequest; 028import org.jdrupes.builder.core.AbstractGenerator; 029import static org.jdrupes.builder.java.JavaTypes.*; 030 031/// Provides [FileTree]s with classes from a given classpath. 032/// 033public class ClasspathScanner extends AbstractGenerator { 034 035 private final String path; 036 037 /// Instantiates a new classpath provider. The `path` is a list of 038 /// directories or jar files separated by the system's path separator. 039 /// Relative paths are resolved against the project's directory. 040 /// 041 /// @param project the project 042 /// @param path the path 043 /// 044 public ClasspathScanner(Project project, String path) { 045 super(project); 046 this.path = path; 047 } 048 049 /// Provide [FileTree]s with classes from a given classpath if the 050 /// requested resource is of type 051 /// [ClasspathElement](javadoc/org/jdrupes/builder/java/ClasspathElement.html). 052 /// 053 /// @param <T> the requested type 054 /// @param requested the requested resources 055 /// @return the stream 056 /// 057 @Override 058 protected <T extends Resource> Stream<T> 059 doProvide(ResourceRequest<T> requested) { 060 // This supports requests for classpath elements only. 061 if (!requested.collects(ClasspathElementType)) { 062 return Stream.empty(); 063 } 064 065 // Map special requests ([RuntimeResources], [CompilationResources]) 066 // to the base request 067 if (!ClasspathType.rawType().equals(requested.type().rawType())) { 068 return project().from(this) 069 .get(requested.widened(ClasspathType.rawType())); 070 } 071 072 @SuppressWarnings("unchecked") 073 var result = (Stream<T>) Stream.of(path.split(File.pathSeparator)) 074 .map(Path::of).map(p -> project().directory().resolve(p)).map(p -> { 075 if (p.toFile().isDirectory()) { 076 return (ClasspathElement) project().newResource( 077 ClassTreeType, p.toAbsolutePath()); 078 } else { 079 return (ClasspathElement) project() 080 .newResource(LibraryJarFileType, p.toAbsolutePath()); 081 } 082 }).filter(e -> requested.collects(e.type())); 083 return result; 084 } 085 086}