All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.robozonky.common.remote.PaginatedApi Maven / Gradle / Ivy

/*
 * Copyright 2019 The RoboZonky Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.robozonky.common.remote;

import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

import com.github.robozonky.api.remote.entities.ZonkyApiToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;

class PaginatedApi {

    private static final Logger LOGGER = LogManager.getLogger(PaginatedApi.class);

    private final Class api;
    private final String url;
    private final ResteasyClient client;
    private final Supplier tokenSupplier;

    PaginatedApi(final Class api, final String url, final Supplier token,
                 final ResteasyClient client) {
        this.api = api;
        this.url = url;
        this.client = client;
        this.tokenSupplier = token;
    }

    /**
     * Filters are for one-time use only. They need to be thrown away after being used, as they could otherwise be used
     * to store and transfer stale state, such as request headers etc. For the same reason, they must not be shared
     * among threads.
     * @return
     */
    private RoboZonkyFilter newFilter() {
        return new AuthenticatedFilter(tokenSupplier);
    }

    public  Q execute(final Function function) {
        return this.execute(function, new Select(), newFilter());
    }

     Q execute(final Function function, final Select select, final RoboZonkyFilter filter) {
        select.accept(filter);
        return execute(function, filter);
    }

     Q execute(final Function function, final RoboZonkyFilter filter) {
        final T proxy = ProxyFactory.newProxy(client, filter, api, url);
        return Api.call(function, proxy);
    }

    public PaginatedResult execute(final Function> function, final Select select, final int pageNo,
                                      final int pageSize) {
        return this.execute(function, select, pageNo, pageSize, newFilter());
    }

    PaginatedResult execute(final Function> function, final Select select, final int pageNo,
                               final int pageSize, final RoboZonkyFilter filter) {
        filter.setRequestHeader("X-Page", String.valueOf(pageNo));
        filter.setRequestHeader("X-Size", String.valueOf(pageSize));
        LOGGER.trace("Will request page #{} of size {}.", pageNo, pageSize);
        final List result = this.execute(function, select, filter);
        final int totalSize = filter.getLastResponseHeader("X-Total")
                .map(Integer::parseInt)
                .orElse(0);
        LOGGER.trace("Has {} results in total.", totalSize);
        return new PaginatedResult<>(result, totalSize);
    }
}