001/*
002 * JDrupes Builder
003 * Copyright (C) 2025, 2026 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.api;
020
021import java.util.EnumSet;
022import java.util.Set;
023import java.util.stream.Stream;
024
025/// Represents a request for [Resource]s of a specified type.
026/// The specified type provides two kinds of type information:
027///
028/// 1. The type of the [Resource]s that are actually provided.
029/// 2. The type of the "context" in which the [Resource]s are to be provided.
030///
031/// As an example, consider requests for a compile time and a runtime
032/// classpath. In both cases, the actually provided [Resource]s are
033/// of type "classpath element". However, depending on the kind of
034/// classpath, a [ResourceProvider] may deliver different collections of
035/// instances of "classpath elements". So instead of requesting
036/// "classpath element", 
037///
038/// Not all requested resource types require context information. For
039/// example, a request for [Cleanliness] usually refers to all resources
040/// that a [Generator] has created and does not depend on a context.
041/// However, in order to keep the API simple, the context is always
042/// required. 
043///
044/// @param <T> the collected type
045///
046public interface ResourceQuery<T extends Resource> {
047
048    /// Return the requested type.
049    ///
050    /// @return the resource type
051    ///
052    ResourceType<? extends T> type();
053
054    ResourceQuery<T> using(Set<Intent> intends);
055
056    default ResourceQuery<T> using(Intent intend, Intent... intends) {
057        return using(EnumSet.of(intend, intends));
058    }
059
060    default ResourceQuery<T> usingAll() {
061        return using(EnumSet.allOf(Intent.class));
062    }
063
064    Set<Intent> uses();
065
066    /// Checks if the query accepts results of the given type. 
067    ///
068    /// @param type the type to check
069    /// @return true, if successful
070    ///
071    boolean wants(ResourceType<?> type);
072}