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.core; 020 021import java.util.Arrays; 022import java.util.EnumSet; 023import java.util.Objects; 024import java.util.Optional; 025import java.util.Set; 026import java.util.stream.Collectors; 027import org.jdrupes.builder.api.Intent; 028import org.jdrupes.builder.api.Project; 029import org.jdrupes.builder.api.Resource; 030import org.jdrupes.builder.api.ResourceRequest; 031import org.jdrupes.builder.api.ResourceType; 032 033/// An implementation of [ResourceRequest]. 034/// 035/// @param <T> the resource type 036/// 037public class DefaultResourceRequest<T extends Resource> 038 implements ResourceRequest<T> { 039 040 private final ResourceType<? extends T> type; 041 private Project[] queried; 042 private Set<Intent> uses; 043 private String name; 044 045 /// Instantiates a new resource request without any intents. 046 /// 047 /// @param type the requested type 048 /// 049 /* default */ DefaultResourceRequest(ResourceType<? extends T> type) { 050 this.type = Objects.requireNonNull(type); 051 uses = EnumSet.noneOf(Intent.class); 052 queried = new Project[0]; 053 } 054 055 @Override 056 @SuppressWarnings("unchecked") 057 public DefaultResourceRequest<T> clone() { 058 try { 059 // This class is immutable 060 return (DefaultResourceRequest<T>) super.clone(); 061 } catch (CloneNotSupportedException e) { 062 throw new IllegalStateException(e); 063 } 064 } 065 066 @Override 067 public ResourceType<? extends T> type() { 068 return type; 069 } 070 071 @Override 072 public ResourceRequest<T> withName(String name) { 073 var result = clone(); 074 result.name = name; 075 return result; 076 } 077 078 @Override 079 public Optional<String> name() { 080 return Optional.ofNullable(name); 081 } 082 083 @Override 084 public ResourceRequest<T> using(Set<Intent> intents) { 085 var result = clone(); 086 result.uses = Objects.requireNonNull(intents); 087 return result; 088 } 089 090 @Override 091 public Set<Intent> uses() { 092 return EnumSet.copyOf(uses); 093 } 094 095 @Override 096 public boolean accepts(ResourceType<?> type) { 097 return this.type.isAssignableFrom(type); 098 } 099 100 @Override 101 public boolean requires(ResourceType<?> type) { 102 return type.isAssignableFrom(this.type); 103 } 104 105 @SuppressWarnings("PMD.MethodReturnsInternalArray") 106 /* default */ Project[] queried() { 107 return queried; 108 } 109 110 /* default */ DefaultResourceRequest<T> queried(Project project) { 111 var newQueried = Arrays.copyOf(queried, queried.length + 1); 112 newQueried[newQueried.length - 1] = Objects.requireNonNull(project); 113 var result = clone(); 114 result.queried = newQueried; 115 return result; 116 } 117 118 @Override 119 public int hashCode() { 120 return Objects.hash(type, name, uses); 121 } 122 123 @Override 124 public boolean equals(Object obj) { 125 if (this == obj) { 126 return true; 127 } 128 if (obj == null) { 129 return false; 130 } 131 if (getClass() != obj.getClass()) { 132 return false; 133 } 134 DefaultResourceRequest<?> other = (DefaultResourceRequest<?>) obj; 135 return Objects.equals(type, other.type) 136 && Objects.equals(name, other.name) 137 && Objects.equals(uses, other.uses); 138 } 139 140 @Override 141 public String toString() { 142 return "ResourceRequest<" + type + ">" 143 + name().map(n -> ":" + n).orElse("") + " [" + uses.stream() 144 .map(Intent::toString).collect(Collectors.joining(", ")) 145 + "]"; 146 } 147 148}