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.core;
020
021import java.util.stream.Stream;
022import org.jdrupes.builder.api.Project;
023import org.jdrupes.builder.api.Resource;
024import org.jdrupes.builder.api.ResourceRequest;
025import org.jdrupes.builder.api.ResourceType;
026import org.jdrupes.builder.api.Resources;
027
028/// A provider of resources to be included in a project. This
029/// implementation can be used for all kinds of resources. Usually
030/// language specific packages derive specializations that bind
031/// this class to a specific type of resource. These specializations
032/// often also offer methods that ease the specification of resources
033/// to be included.
034///
035/// @param <T> the resource type
036///
037public class ResourceCollector<T extends Resource> extends AbstractGenerator {
038
039    private final ResourceType<T> type;
040    private final Resources<T> resources;
041
042    /// Instantiates a new resources collector.
043    ///
044    /// @param project the project
045    /// @param type the type of resources to collect
046    ///
047    public ResourceCollector(Project project, ResourceType<T> type) {
048        super(project);
049        this.type = type;
050        resources
051            = project()
052                .newResource(new ResourceType<>(Resources.class, type) {});
053    }
054
055    /// Adds the given file tree with resource directories.
056    ///
057    /// @param resources the resources
058    /// @return the resources collector
059    ///
060    public final ResourceCollector<T> add(T resources) {
061        this.resources.add(resources);
062        return this;
063    }
064
065    /// Adds the given file trees with resource directories.
066    ///
067    /// @param resources the resources
068    /// @return the resources collector
069    ///
070    public final ResourceCollector<T> add(Stream<T> resources) {
071        this.resources.addAll(resources);
072        return this;
073    }
074
075    /// Return the resources to collect.
076    ///
077    /// @return the resources
078    ///
079    public final Resources<T> resources() {
080        return resources;
081    }
082
083    @Override
084    @SuppressWarnings("unchecked")
085    protected <R extends Resource> Stream<R>
086            doProvide(ResourceRequest<R> requested) {
087        if (!requested.type().containedType().isAssignableFrom(type)) {
088            return Stream.empty();
089        }
090        return (Stream<R>) resources.stream();
091    }
092
093}