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.api;
020
021import java.time.Instant;
022import java.time.ZoneId;
023import java.time.format.DateTimeFormatter;
024import java.time.format.FormatStyle;
025import java.util.Optional;
026
027/// Represents a resource handled by the builder. Resources can have names
028/// that may be referenced in [ResourceRequest]s.
029///
030public interface Resource {
031
032    /// The instant at which this resource was created or last modified.
033    ///
034    /// @return the instant
035    ///
036    default Optional<Instant> asOf() {
037        return Optional.empty();
038    }
039
040    /// Checks if this resource is newer than the other.
041    ///
042    /// @param other the other
043    /// @return true, if is newer than
044    ///
045    @SuppressWarnings("PMD.SimplifyBooleanReturns")
046    default boolean isNewerThan(Resource other) {
047        if (asOf().isEmpty() && other.asOf().isEmpty()) {
048            return false;
049        }
050        if (asOf().isEmpty()) {
051            return false;
052        }
053        if (other.asOf().isEmpty()) {
054            return true;
055        }
056        return asOf().get().isAfter(other.asOf().get());
057    }
058
059    /// Returns the type of this resource.
060    ///
061    /// @return the type
062    ///
063    ResourceType<?> type();
064
065    /// Returns the name of this resource if set.
066    ///
067    /// @return the optional
068    ///
069    Optional<String> name();
070
071    /// Cleanup the resource. This method is called by [ResourceProvider]s
072    /// in response to a request for [Cleanliness]. The default
073    /// implementation does nothing. Derived classes should override this
074    /// and delete any physical representation of the resource.
075    ///
076    default void cleanup() {
077        // Do nothing
078    }
079
080    /// Returns a localized string representation of the instant
081    /// at which this resource was created or last modified.
082    ///
083    /// @return the string
084    ///
085    default String asOfLocalized() {
086        var asOf = asOf();
087        if (asOf.isEmpty()) {
088            return "non-existant";
089        }
090        return DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
091            .format(asOf.get().atZone(ZoneId.systemDefault()));
092    }
093}