Vote.java

/*
 * Copyright © 2012-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.domain.site;

import java.text.MessageFormat;
import java.time.LocalDateTime;

import org.ctan.site.domain.AbstractEntity;
import org.ctan.site.domain.account.User;
import org.ctan.site.domain.catalogue.Pkg;
import org.ctan.site.services.DateUtils;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.google.common.collect.ImmutableMap;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder.Default;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

/**
 * The domain class <code>Vote</code> contains the description of a forbidden
 * word in the guest book on the site.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
@Entity
@Table(name = "vote")
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@SuppressFBWarnings(value = "EI_EXPOSE_REP")
public class Vote extends AbstractEntity {

    /**
     * The field <code>rating</code> contains the number of stars. It has a
     * value from 1 to 5.
     */
    @Column(name = "rating")
    private int rating;

    /**
     * The field <code>expertise</code> contains the expertise of the voter. It
     * has a value from 0 to 4.
     */
    @Column(name = "expertise")
    private int expertise;

    /**
     * The field <code>comment</code> contains the optional comment of the
     * voter.
     */
    @Column(length = 1024, name = "comment")
    @Default
    private String comment = "";

    /**
     * The field <code>lastModified</code> contains the date time stamp.
     */
    @Column(name = "last_modified")
    @JsonFormat(pattern = "dd-MM-yyyy hh:mm:ss")
    private LocalDateTime lastModified;

    /**
     * The field <code>user</code> contains the reference to the user.
     */
    @ManyToOne(optional = false)
    @JsonManagedReference
    @EqualsAndHashCode.Exclude
    private User user;

    /**
     * The field <code>pkg</code> contains the reference to the package.
     */
    @ManyToOne(optional = false)
    @JsonManagedReference
    @EqualsAndHashCode.Exclude
    private Pkg pkg;

    /**
     * The method <code>getDate</code> provides means to get the modification
     * time as day. If the modification time is null then the empty string is
     * returned.
     *
     * @return he ISO date for the day
     */
    public String getDate() {

        return lastModified == null ? "" : DateUtils.formatDate(lastModified);
    }

    /**
     * The method <code>toMap</code> provides means to get the instance as an
     * immutable Map.
     *
     * @return the Map
     */
    public ImmutableMap<String, Object> toMap() {

        return ImmutableMap.of("id", (Object) getId(),
            "rating", rating,
            "experience", expertise,
            "comment", comment,
            "date", DateUtils.formatDateTime(lastModified),
            "pkg", pkg.getKey(),
            "user", user.getAccount());
    }

    /**
     * {@inheritDoc}
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {

        return MessageFormat.format("{2} {3}: {0} {1}",
            "*".repeat(rating),
            comment.length() < 16 ? comment : comment.substring(0, 16),
            user,
            "+".repeat(expertise));
    }
}