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