Upload3Resource.java

/*
 * Copyright © 2023-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.resources.upload;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;

import org.ctan.site.services.upload.UploadService;
import org.ctan.site.services.upload.UploadService.IncomingTo;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.dropwizard.hibernate.UnitOfWork;
import jakarta.annotation.security.PermitAll;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response.Status;
import lombok.NonNull;

/**
 * The class <code>Upload3Resource</code> contains the controller for the upload
 * resource.
 *
 * @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
 */
@Path("/3.0/upload")
@Produces(MediaType.APPLICATION_JSON)
public class Upload3Resource {

    /**
     * The field <code>service</code> contains the underlying service.
     */
    private UploadService service;

    /**
     * This is the constructor for the class <code>TexArchive3Resource</code>.
     *
     * @param service the underlying service
     */
    @SuppressFBWarnings(value = {"CT_CONSTRUCTOR_THROW", "EI_EXPOSE_REP2"})
    public Upload3Resource(@NonNull UploadService service) {

        this.service = service;
    }

    /**
     * The method <code>getAddendum</code> provides means to retrieve the upload
     * addendum file.
     *
     * @return the addendum
     */
    @GET
    @Path("/addendum")
    public Map<String, String> getAddendum() {

        try {
            return service.getAddendum();
        } catch (IOException e) {
            throw new WebApplicationException(Status.NOT_FOUND);
        }
    }

    /**
     * The method <code>getList</code> provides means to retrieve the list of
     * unprocessed uploads.
     *
     * @param query the query pattern
     * @param page the current page
     * @param pageSize the page size
     * @param orderBy the attribute to order by
     * @param asc sort ascending
     * @return the list of upload items
     */
    @GET
    @Path("/incoming")
    @UnitOfWork(value = "siteDb")
    public IncomingTo getIncoming(
        @QueryParam("q") String query,
        @QueryParam("page") Long page,
        @QueryParam("size") Long pageSize,
        @QueryParam("order") String orderBy,
        @QueryParam("asc") Boolean asc) {

        try {
            return service.getIncoming(null,
                page == null ? 0L : page,
                pageSize == null ? 100L : pageSize,
                null,
                null);
        } catch (IllegalArgumentException e) {
            throw new WebApplicationException(Status.BAD_REQUEST);
        } catch (FileNotFoundException e) {
            throw new WebApplicationException(Status.NOT_FOUND);
        }
    }

    /**
     * The method <code>getStatistics</code> provides means to retrieve the
     * cached upload statistics. The upload statistics contains the number of
     * uploads per month.
     *
     * <p>
     * The statistics are cached and updated every 30 minutes.
     * </p>
     *
     * @return the statistics
     */
    @GET
    @Path("/statistics")
    @PermitAll
    @UnitOfWork(value = "siteDb")
    public Map<String, Integer> getStatistics() {

        return service.getStatistics();
    }

    /**
     * The method <code>getVersion</code> provides means to retrieve the version
     * number of the API.
     *
     * @return a Map with a single attribute <code>version</code> containing the
     *     version number as String.
     */
    @GET
    @Path("/version")
    public Map<String, String> getVersion() {

        return Map.of("version", "3.0");
    }

}