001/*
002 * JDrupes Builder
003 * Copyright (C) 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.java;
020
021import java.util.Objects;
022import java.util.Optional;
023import java.util.jar.Attributes;
024import org.jdrupes.builder.api.Resource;
025import org.jdrupes.builder.api.ResourceFactory;
026import org.jdrupes.builder.api.ResourceType;
027import org.jdrupes.builder.core.ResourceObject;
028import static org.jdrupes.builder.java.JavaTypes.ManifestAttributesType;
029
030/// A wrapper around [Attributes] to allow their usage as [Resource].
031/// Because [Attributes] is a class and not an interface, this resource
032/// type cannot be specialized without an actual implementation.
033///
034public class ManifestAttributes extends Attributes implements Resource {
035
036    private final ResourceObject resourceDelegee;
037
038    /// Initializes a new manifest attributes.
039    ///
040    public ManifestAttributes() {
041        this.resourceDelegee = new ResourceObject(ManifestAttributesType) {};
042    }
043
044    @Override
045    public ResourceType<?> type() {
046        return resourceDelegee.type();
047    }
048
049    @Override
050    public Optional<String> name() {
051        return resourceDelegee.name();
052    }
053
054    /// Sets the name of the resource.
055    ///
056    /// @param name the name
057    /// @return the resource object
058    ///
059    @SuppressWarnings("PMD.LooseCoupling")
060    public final ManifestAttributes name(String name) {
061        resourceDelegee.name(name);
062        return this;
063    }
064
065    @Override
066    public Object put(Object name, Object value) {
067        if (resourceDelegee.isLocked()) {
068            throw new IllegalStateException(
069                "Attributes may only be set immediately after creation.");
070        }
071        return super.put(name, value);
072    }
073
074    @Override
075    public Object remove(Object name) {
076        if (resourceDelegee.isLocked()) {
077            throw new IllegalStateException(
078                "Attributes may only be removed immediately after creation.");
079        }
080        return super.remove(name);
081    }
082
083    @Override
084    public int hashCode() {
085        final int prime = 31;
086        int result = super.hashCode();
087        result = prime * result + Objects.hash(resourceDelegee);
088        return result;
089    }
090
091    @Override
092    public boolean equals(Object obj) {
093        if (this == obj) {
094            return true;
095        }
096        if (!super.equals(obj)) {
097            return false;
098        }
099        if (!(obj instanceof ManifestAttributes)) {
100            return false;
101        }
102        @SuppressWarnings("PMD.LooseCoupling")
103        ManifestAttributes other = (ManifestAttributes) obj;
104        return Objects.equals(resourceDelegee, other.resourceDelegee);
105    }
106
107    /// Creates a new manifest attributes resource.
108    ///
109    /// @return the manifest attributes
110    ///
111    @SuppressWarnings("PMD.LooseCoupling")
112    public static ManifestAttributes create() {
113        return ResourceFactory.create(ManifestAttributesType);
114    }
115
116}