NullCheck.java

/*
 * Copyright © 2025 The CTAN Team and individual authors
 *
 * This file is distributed under the 3-clause BSD license.
 * See file LICENSE for details.
 */

package org.ctan.site.services.util;

import java.time.LocalDateTime;

import org.ctan.site.domain.catalogue.Upload;
import org.ctan.site.domain.catalogue.Upload.TerminationStatus;

import lombok.NonNull;

/**
 * The class <code>NullCheck</code> contains the utility methods for treatment
 * of null values.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
public interface NullCheck {

    /**
     * The method <code>copyNonNull</code> provides means to create a copy
     * without null values.
     *
     * @param value the input
     * @return a shallow copy
     */
    static Boolean copyNonNull(Boolean value) {

        return value != null ? value : Boolean.FALSE;
    }

    /**
     * The method <code>copyNonNull</code> provides means to create a copy
     * without null values.
     *
     * @param value the input
     * @return a shallow copy
     */
    static LocalDateTime copyNonNull(LocalDateTime value) {

        return value != null ? value : LocalDateTime.now();
    }

    /**
     * The method <code>copyNonNull</code> provides means to create a copy
     * without null values.
     *
     * @param value the input
     * @return a shallow copy
     */
    static Long copyNonNull(Long value) {

        return value != null ? value : 0L;
    }

    /**
     * The method <code>copyNonNull</code> provides means to create a copy
     * without null values.
     *
     * @param value the input
     * @return a shallow copy
     */
    static String copyNonNull(String value) {

        return value != null ? value : "";
    }

    /**
     * The method <code>copyNonNull</code> provides means to create a copy
     * without null values.
     *
     * @param value the input
     * @return a shallow copy
     */
    static TerminationStatus copyNonNull(TerminationStatus value) {

        return value != null ? value : TerminationStatus.UNKNOWN;
    }

    /**
     * The method <code>copyNonNull</code> provides means to create a shallow
     * copy without null values.
     *
     * @param up the input
     * @return a shallow copy
     */
    static Upload copyNonNull(@NonNull Upload up) {

        return Upload.builder()
            .announce(copyNonNull(up.getAnnounce()))
            .announcement(copyNonNull(up.getAnnouncement()))
            .authors(copyNonNull(up.getAuthors()))
            .bugs(copyNonNull(up.getBugs()))
            .confirm(copyNonNull(up.getConfirm()))
            .ctanPath(copyNonNull(up.getCtanPath()))
            .dateCreated(copyNonNull(up.getDateCreated()))
            .description(copyNonNull(up.getDescription()))
            .development(copyNonNull(up.getDevelopment()))
            .email(copyNonNull(up.getEmail()))
            .home(copyNonNull(up.getHome()))
            .id(copyNonNull(up.getId()))
            .lastUpdated(copyNonNull(up.getLastUpdated()))
            .license(copyNonNull(up.getLicense()))
            .mailinglist(copyNonNull(up.getMailinglist()))
            .note(copyNonNull(up.getNote()))
            .pkg(copyNonNull(up.getPkg()))
            .repository(copyNonNull(up.getRepository()))
            .serverUrl(copyNonNull(up.getServerUrl()))
            .status(copyNonNull(up.getStatus()))
            .summary(copyNonNull(up.getSummary()))
            .support(copyNonNull(up.getSupport()))
            .topics(copyNonNull(up.getTopics()))
            .type(copyNonNull(up.getType()))
            .uploader(copyNonNull(up.getUploader()))
            .vers(copyNonNull(up.getVers()))
            .version(copyNonNull(up.getVersion()))
            .build();
    }

    /**
     * The method <code>isNotNull</code> provides means to check the value for
     * null and throw a {@link NullPointerException} if the value is null.
     *
     * @param value the value
     * @param msg the name of the parameter
     * @return the value
     */
    static String isNotNull(String value, String msg) {

        if (value == null) {
            throw new NullPointerException(
                msg + " is marked non-null but is null");
        }
        return value;
    }

    /**
     * The method <code>isNotNullObject</code> provides means to check the value
     * for null and throw a {@link NullPointerException} if the value is null.
     *
     * @param value the value
     * @param msg the name of the parameter
     */
    static void isNotNullObject(Object value, String msg) {

        if (value == null) {
            throw new NullPointerException(
                msg + " is marked non-null but is null");
        }
    }
}