001/*
002 * JDrupes Builder
003 * Copyright (C) 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.stream.Stream;
022
023/// This interface must be made available to the [BuildContext]
024/// by implementations of resource providers.
025///
026@SuppressWarnings("PMD.ImplicitFunctionalInterface")
027public interface ResourceProviderSpi {
028
029    /// Provide the requested resources. This method is not intended
030    /// to be invoked directly. Rather, it must be invoked via
031    /// [BuildContext#resources].
032    /// 
033    /// When properly invoked through [BuildContext#resources], this
034    /// method is never invoked twice for the same request (unless there
035    /// has been a request for [Cleanliness] in between). The method
036    /// may, however, be invoked concurrently for different requests.
037    /// 
038    /// Providers that evaluate all potentially provided resources anyway
039    /// and return only a subset for some actually requested
040    /// [ResourceType]s should therefore invoke themselves through
041    /// [ResourceProvider#resources] with a request for all resources and
042    /// filter the (automatically cached) result.
043    /// 
044    /// Special care must be taken when handling resource type hierarchies.
045    /// If [ResourceType] B extends ResourceType A and the provider
046    /// provides ResourceType B, it must also provide its resources
047    /// in response to a request for ResourceType A. However, the caching
048    /// mechanism is unaware of relationships between resource types.
049    /// Requests for A and B are therefore forwarded independently.
050    /// To avoid duplicate evaluation, the provider must map a request
051    /// for A to a request for B (via [ResourceProvider#resources]).   
052    ///
053    /// @param <T> the type of the requested (and provided) resource
054    /// @param request the request for resources
055    /// @return the provided resource(s) as stream
056    ///
057    <T extends Resource> Stream<T> provide(ResourceRequest<T> request);
058}