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.logging.Level; 022import java.util.logging.Logger; 023import java.util.stream.Stream; 024import org.jdrupes.builder.api.BuildContext; 025import org.jdrupes.builder.api.Resource; 026import org.jdrupes.builder.api.ResourceProvider; 027import org.jdrupes.builder.api.ResourceRequest; 028 029/// A base implementation for[ResourceProvider]s. 030/// 031public abstract class AbstractProvider implements ResourceProvider { 032 033 /// The log. 034 @SuppressWarnings("PMD.LambdaCanBeMethodReference") 035 // Use first non-anomymous class for logger. 036 protected final Logger log = Logger.getLogger( 037 Stream.iterate((Class<?>) getClass(), 038 c -> c != null, (Class<?> c) -> c.getSuperclass()) 039 .filter(c -> !c.isAnonymousClass()) 040 .findFirst().get().getName()); 041 042 /// Initializes a new abstract provider. 043 /// 044 @SuppressWarnings("PMD.UnnecessaryConstructor") 045 public AbstractProvider() { 046 // Make javadoc happy. 047 } 048 049 /// Checks if the the current thread executes a provider invocation 050 /// from [BuildContext#get]. Generates a warning if the invocation 051 /// is not allowed. Then invokes [#doProvide]. 052 /// 053 /// @return true, if allowed 054 /// 055 @Override 056 @SuppressWarnings("PMD.GuardLogStatement") 057 public final <T extends Resource> Stream<T> 058 provide(ResourceRequest<T> requested) { 059 if (!FutureStream.isProviderInvocationAllowed()) { 060 log.log(Level.WARNING, new IllegalStateException(), 061 () -> "Direct invocation of " + this + " is not allowed"); 062 } 063 return doProvide(requested); 064 } 065 066 /// Invoked by [#provide] after checking if the invocation is allowed. 067 /// 068 /// @param <T> the generic type 069 /// @param requested the requested 070 /// @return the stream 071 /// 072 protected abstract <T extends Resource> Stream<T> 073 doProvide(ResourceRequest<T> requested); 074 075 @Override 076 public String toString() { 077 return "Provider " + getClass().getSimpleName(); 078 } 079}