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.HashSet; 022import java.util.Set; 023import java.util.function.Consumer; 024import java.util.stream.Stream; 025 026/// Helper class for implementing [Project#from]. 027/// 028public class FromHelper { 029 private final BuildContext context; 030 private final Stream<ResourceProvider> providers; 031 private final Set<ResourceProvider> excluded = new HashSet<>(); 032 private final Set<Class<? extends ResourceProvider>> excludedTypes 033 = new HashSet<>(); 034 private Consumer<ResourceProvider> providerLog = _ -> { 035 }; 036 037 /// Initializes a new from helper. 038 /// 039 /// @param context the context 040 /// @param providers the providers 041 /// 042 public FromHelper(BuildContext context, 043 Stream<ResourceProvider> providers) { 044 this.context = context; 045 this.providers = providers; 046 } 047 048 /// Exclude the given provider when requesting resources. 049 /// 050 /// @param provider the provider 051 /// @return the from helper 052 /// 053 public FromHelper without(ResourceProvider provider) { 054 excluded.add(provider); 055 return this; 056 } 057 058 /// Exclude providers of the given type when requesting resources. 059 /// 060 /// @param providerType the provider type 061 /// @return the from helper 062 /// 063 public FromHelper 064 without(Class<? extends ResourceProvider> providerType) { 065 excludedTypes.add(providerType); 066 return this; 067 } 068 069 /// Register a callback for logging the providers used. 070 /// 071 /// @param providerLog the provider log 072 /// @return the from helper 073 /// 074 public FromHelper log(Consumer<ResourceProvider> providerLog) { 075 this.providerLog = providerLog; 076 return this; 077 } 078 079 /// Returns the requested resources using the context and providers 080 /// passed to the record's constructor. 081 /// 082 /// @param <T> the generic type 083 /// @param request the request 084 /// @return the stream 085 /// 086 public <T extends Resource> Stream<T> get(ResourceRequest<T> request) { 087 return providers.filter(p -> !excluded.contains(p)) 088 .filter(p -> excludedTypes.stream() 089 .filter(t -> t.isAssignableFrom(p.getClass())).findAny() 090 .isEmpty()) 091 .peek(providerLog::accept) 092 .flatMap(provider -> context.fetch(provider, request)); 093 } 094}