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 String path;
036
037    /// Instantiates a new classpath provider. The path needs to be
038    /// set with [#path].
039    ///
040    /// @param project the project
041    ///
042    public ClasspathScanner(Project project) {
043        super(project);
044        path = "";
045    }
046
047    /// Sets the path. The `path` is a list of directories or jar
048    /// files separated by the system's path separator. Relative
049    /// paths are resolved against the project's directory.
050    ///
051    /// @param path the path
052    /// @return the classpath scanner
053    ///
054    public ClasspathScanner path(String path) {
055        this.path = path;
056        return this;
057    }
058
059    /// Provide [FileTree]s with classes from a given classpath if the
060    /// requested resource is of type 
061    /// [ClasspathElement](javadoc/org/jdrupes/builder/java/ClasspathElement.html).
062    ///
063    /// @param <T> the requested type
064    /// @param requested the requested resources
065    /// @return the stream
066    ///
067    @Override
068    protected <T extends Resource> Stream<T>
069            doProvide(ResourceRequest<T> requested) {
070        // This supports requests for classpath elements only.
071        if (!requested.accepts(ClasspathElementType)) {
072            return Stream.empty();
073        }
074
075        @SuppressWarnings("unchecked")
076        var result = (Stream<T>) Stream.of(path.split(File.pathSeparator))
077            .map(Path::of).map(p -> project().directory().resolve(p)).map(p -> {
078                if (p.toFile().isDirectory()) {
079                    return ClassTree.of(project(), p.toAbsolutePath());
080                } else {
081                    return LibraryJarFile.of(p.toAbsolutePath());
082                }
083            }).filter(e -> requested.accepts(e.type()));
084        return result;
085    }
086
087}