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

graphql.relay.SimpleListConnection Maven / Gradle / Ivy

The newest version!
package graphql.relay;

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static java.util.Base64.getDecoder;
import static java.util.Base64.getEncoder;

public class SimpleListConnection implements DataFetcher> {

    private static final String DUMMY_CURSOR_PREFIX = "simple-cursor";
    private final String prefix;
    private final List data;

    public SimpleListConnection(List data, String prefix) {
        if (prefix == null || prefix.length() == 0) {
            throw new IllegalArgumentException("prefix cannot be null or empty");
        }
        this.prefix = prefix;
        this.data = data;
    }

    public SimpleListConnection(List data) {
        this(data, DUMMY_CURSOR_PREFIX);
    }

    private List> buildEdges() {
        List> edges = new ArrayList<>();
        int ix = 0;
        for (T object : data) {
            edges.add(new DefaultEdge<>(object, new DefaultConnectionCursor(createCursor(ix++))));
        }
        return edges;
    }

    @Override
    public Connection get(DataFetchingEnvironment environment) {

        List> edges = buildEdges();

        int afterOffset = getOffsetFromCursor(environment.getArgument("after"), -1);
        int begin = Math.max(afterOffset, -1) + 1;
        int beforeOffset = getOffsetFromCursor(environment.getArgument("before"), edges.size());
        int end = Math.min(beforeOffset, edges.size());

        edges = edges.subList(begin, end);
        if (edges.size() == 0) {
            return emptyConnection();
        }

        Integer first = environment.getArgument("first");
        Integer last = environment.getArgument("last");

        ConnectionCursor firstPresliceCursor = edges.get(0).getCursor();
        ConnectionCursor lastPresliceCursor = edges.get(edges.size() - 1).getCursor();

        if (first != null) {
            edges = edges.subList(0, first <= edges.size() ? first : edges.size());
        }
        if (last != null) {
            edges = edges.subList(last > edges.size() ? 0 : edges.size() - last, edges.size());
        }

        if (edges.isEmpty()) {
            return emptyConnection();
        }

        Edge firstEdge = edges.get(0);
        Edge lastEdge = edges.get(edges.size() - 1);

        PageInfo pageInfo = new DefaultPageInfo(
            firstEdge.getCursor(),
            lastEdge.getCursor(),
            !firstEdge.getCursor().equals(firstPresliceCursor),
            !lastEdge.getCursor().equals(lastPresliceCursor)
        );

        return new DefaultConnection<>(
                edges,
                pageInfo
        );
    }

    private Connection emptyConnection() {
        PageInfo pageInfo = new DefaultPageInfo(null, null, false, false);
        return new DefaultConnection<>(Collections.emptyList(), pageInfo);
    }

    /**
     * find the object's cursor, or null if the object is not in this connection.
     * @param object the object in play
     * @return a connection cursor
     */
    public ConnectionCursor cursorForObjectInConnection(T object) {
        int index = data.indexOf(object);
        if (index == -1) {
            return null;
        }
        String cursor = createCursor(index);
        return new DefaultConnectionCursor(cursor);
    }

    private int getOffsetFromCursor(String cursor, int defaultValue) {
        if (cursor == null) {
            return defaultValue;
        }
        String string = new String(getDecoder().decode(cursor), StandardCharsets.UTF_8);
        return Integer.parseInt(string.substring(prefix.length()));
    }

    private String createCursor(int offset) {
        byte[] bytes = (prefix + Integer.toString(offset)).getBytes(StandardCharsets.UTF_8);
        return getEncoder().encodeToString(bytes);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy