<commit_before>package uk.gov.register.resources.v2;

import com.codahale.metrics.annotation.Timed;
import io.dropwizard.jersey.params.IntParam;
import uk.gov.register.core.EntryType;
import uk.gov.register.core.Field;
import uk.gov.register.core.HashingAlgorithm;
import uk.gov.register.core.Item;
import uk.gov.register.core.RegisterReadOnly;
import uk.gov.register.exceptions.FieldConversionException;
import uk.gov.register.providers.params.IntegerParam;
import uk.gov.register.resources.HttpServletResponseAdapter;
import uk.gov.register.resources.RequestContext;
import uk.gov.register.resources.StartLimitPagination;
import uk.gov.register.service.ItemConverter;
import uk.gov.register.util.HashValue;
import uk.gov.register.views.v2.BlobListView;
import uk.gov.register.views.ItemView;
import uk.gov.register.views.ViewFactory;
import uk.gov.register.views.representations.ExtraMediaType;
import uk.gov.register.views.v2.BlobView;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Path("/next/blobs")
public class BlobResource {
    protected final RegisterReadOnly register;
    protected final ViewFactory viewFactory;
    protected final ItemConverter itemConverter;
    private final HttpServletResponseAdapter httpServletResponseAdapter;

    @Inject
    public BlobResource(RegisterReadOnly register, ViewFactory viewFactory, ItemConverter itemConverter, RequestContext requestContext) {
        this.register = register;
        this.viewFactory = viewFactory;
        this.itemConverter = itemConverter;
        this.httpServletResponseAdapter = new HttpServletResponseAdapter(requestContext.getHttpServletResponse());
    }

    @GET
    @Path("/sha-256:{blob-hash}")
    @Produces({
            MediaType.APPLICATION_JSON,
            ExtraMediaType.TEXT_CSV,
    })
    @Timed
    public BlobView getBlobDataByHex(@PathParam("blob-hash") String blobHash) throws FieldConversionException {
        return getBlob(blobHash).map(this::buildBlobView)
                .orElseThrow(() -> new NotFoundException("No blob found with blob hash: " + blobHash));
    }

    @GET
    @Path("/")
    @Produces({
            MediaType.APPLICATION_JSON,
            ExtraMediaType.TEXT_CSV,
    })
    @Timed
    public BlobListView listBlobs(@QueryParam("start") Optional<String> optionalStart, @QueryParam("limit") Optional<IntegerParam> optionalLimit) throws FieldConversionException {
        Optional<HashValue> start = optionalStart.map(value -> new HashValue(HashingAlgorithm.SHA256, value));
        int limit =  optionalLimit.map(IntParam::get).orElse(100);

        Collection<Item> items = register.getUserItemsPaginated(start, limit + 1);

        boolean hasNext = (items.size() == limit + 1);

        if(hasNext) {
            Item finalBlob = items.stream().skip(limit).findFirst().get();
            String nextStart = finalBlob.getBlobHash().getValue();
            setNextHeader(nextStart, limit);
        }

        return buildBlobListView(items.stream().limit(limit).collect(Collectors.toList()));
    }

    protected Optional<Item> getBlob(String blobHash) {
        HashValue hash = new HashValue(HashingAlgorithm.SHA256, blobHash);
        return register.getItem(hash);
    }

    protected Map<String, Field> getFieldsByName() {
        return register.getFieldsByName();<commit_msg>Simplify blob resource logic for getting the last item<commit_after>package uk.gov.register.resources.v2;

import com.codahale.metrics.annotation.Timed;
import io.dropwizard.jersey.params.IntParam;
import uk.gov.register.core.EntryType;
import uk.gov.register.core.Field;
import uk.gov.register.core.HashingAlgorithm;
import uk.gov.register.core.Item;
import uk.gov.register.core.RegisterReadOnly;
import uk.gov.register.exceptions.FieldConversionException;
import uk.gov.register.providers.params.IntegerParam;
import uk.gov.register.resources.HttpServletResponseAdapter;
import uk.gov.register.resources.RequestContext;
import uk.gov.register.resources.StartLimitPagination;
import uk.gov.register.service.ItemConverter;
import uk.gov.register.util.HashValue;
import uk.gov.register.views.v2.BlobListView;
import uk.gov.register.views.ItemView;
import uk.gov.register.views.ViewFactory;
import uk.gov.register.views.representations.ExtraMediaType;
import uk.gov.register.views.v2.BlobView;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Path("/next/blobs")
public class BlobResource {
    protected final RegisterReadOnly register;
    protected final ViewFactory viewFactory;
    protected final ItemConverter itemConverter;
    private final HttpServletResponseAdapter httpServletResponseAdapter;

    @Inject
    public BlobResource(RegisterReadOnly register, ViewFactory viewFactory, ItemConverter itemConverter, RequestContext requestContext) {
        this.register = register;
        this.viewFactory = viewFactory;
        this.itemConverter = itemConverter;
        this.httpServletResponseAdapter = new HttpServletResponseAdapter(requestContext.getHttpServletResponse());
    }

    @GET
    @Path("/sha-256:{blob-hash}")
    @Produces({
            MediaType.APPLICATION_JSON,
            ExtraMediaType.TEXT_CSV,
    })
    @Timed
    public BlobView getBlobDataByHex(@PathParam("blob-hash") String blobHash) throws FieldConversionException {
        return getBlob(blobHash).map(this::buildBlobView)
                .orElseThrow(() -> new NotFoundException("No blob found with blob hash: " + blobHash));
    }

    @GET
    @Path("/")
    @Produces({
            MediaType.APPLICATION_JSON,
            ExtraMediaType.TEXT_CSV,
    })
    @Timed
    public BlobListView listBlobs(@QueryParam("start") Optional<String> optionalStart, @QueryParam("limit") Optional<IntegerParam> optionalLimit) throws FieldConversionException {
        Optional<HashValue> start = optionalStart.map(value -> new HashValue(HashingAlgorithm.SHA256, value));
        int limit =  optionalLimit.map(IntParam::get).orElse(100);

        Collection<Item> items = register.getUserItemsPaginated(start, limit + 1);
        List<Item> itemsList = new ArrayList<>(items);

        boolean hasNext = (items.size() == limit + 1);

        if(hasNext) {
            Item finalBlob = itemsList.get(limit);
            String nextStart = finalBlob.getBlobHash().getValue();
            setNextHeader(nextStart, limit);
        }

        return buildBlobListView(items.stream().limit(limit).collect(Collectors.toList()));
    }

    protected Optional<Item> getBlob(String blobHash) {
        HashValue hash = new HashValue(HashingAlgorithm.SHA256, blobHash);
        return register.getItem(hash);
    }

    protected Map<String, Field> getFieldsByName() {
        return register.getFieldsByName();
{'fraction_non_alphanumeric': 0.10685675492192803, 'fraction_numerical': 0.00461642905634759, 'mean_word_length': 4.118832522585128, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '935555', 'n_tokens_mistral': 2101, 'n_tokens_neox': 2075, 'n_words': 395}