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.lang.reflect.Proxy; 022import java.util.Collections; 023import java.util.LinkedHashSet; 024import java.util.Objects; 025import java.util.Set; 026import java.util.logging.Logger; 027import java.util.stream.Stream; 028import org.jdrupes.builder.api.Proxyable; 029import org.jdrupes.builder.api.Resource; 030import org.jdrupes.builder.api.ResourceType; 031import org.jdrupes.builder.api.Resources; 032 033/// Represents a set of resources. Resources are added by [add]. 034/// The [stream] method returns a stream of the added resources. 035/// The [stream] method preserves the order in which the resources 036/// were added. 037/// 038/// @param <T> the type of the contained resources 039/// 040public class DefaultResources<T extends Resource> extends ResourceObject 041 implements Resources<T> { 042 043 /// The log. 044 protected final Logger log = Logger.getLogger(getClass().getName()); 045 private final Set<T> content; 046 047 /// Instantiates a new resource set. 048 /// 049 /// @param type the type of this instance as resource 050 /// 051 protected DefaultResources(ResourceType<?> type) { 052 super(type); 053 content = Collections.synchronizedSet(new LinkedHashSet<>()); 054 } 055 056 /* default */ @SuppressWarnings("unchecked") 057 static <T extends Resources<?>> T createResources(ResourceType<T> type) { 058 return (T) Proxy.newProxyInstance(type.rawType().getClassLoader(), 059 new Class<?>[] { type.rawType(), Proxyable.class }, 060 new ForwardingHandler(new DefaultResources<>(type))); 061 } 062 063 @Override 064 public Resources<T> add(T resource) { 065 content.add(resource); 066 return this; 067 } 068 069 @Override 070 public boolean isEmpty() { 071 return content.isEmpty(); 072 } 073 074 @Override 075 public Stream<T> stream() { 076 return content.stream(); 077 } 078 079 @Override 080 public Resources<T> clear() { 081 content.clear(); 082 return this; 083 } 084 085 @Override 086 public int hashCode() { 087 final int prime = 31; 088 int result = super.hashCode(); 089 result = prime * result + Objects.hash(content); 090 return result; 091 } 092 093 @Override 094 public boolean equals(Object obj) { 095 if (this == obj) { 096 return true; 097 } 098 if (!super.equals(obj)) { 099 return false; 100 } 101 return (obj instanceof DefaultResources<?> other) 102 && Objects.equals(content, other.content); 103 } 104 105 @Override 106 public String toString() { 107 return type().toString() + " (" + asOfLocalized() 108 + ") with " + content.size() + " elements"; 109 } 110 111}