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