1- package com .graphql .example .proxy ;
1+ package com .graphql .example .proxy . relay ;
22
33import graphql .relay .Connection ;
44import graphql .relay .ConnectionCursor ;
55import graphql .relay .DefaultConnection ;
6- import graphql .relay .DefaultConnectionCursor ;
76import graphql .relay .DefaultEdge ;
87import graphql .relay .DefaultPageInfo ;
98import graphql .relay .Edge ;
109import graphql .relay .PageInfo ;
1110import graphql .schema .DataFetchingEnvironment ;
1211
13- import java .nio .charset .StandardCharsets ;
1412import java .util .ArrayList ;
1513import java .util .Collections ;
1614import java .util .List ;
1715import java .util .function .Function ;
18- import java .util .regex .Matcher ;
19- import java .util .regex .Pattern ;
2016
2117//
2218// the ice and fire API uses page=n&pageSize=n pagination and we cant know the
3127public class ForwardOnlyFixedPagedDataSet {
3228
3329
34- /**
35- * This uses an encoding of page # plus full offset from the page forward
36- */
37- static class PageAndOffset {
38- private static final java .util .Base64 .Encoder encoder = java .util .Base64 .getEncoder ();
39- private static final java .util .Base64 .Decoder decoder = java .util .Base64 .getDecoder ();
40- private final static Pattern pagePattern = Pattern .compile ("^page=([0-9]*)" );
41- private final static Pattern offsetPattern = Pattern .compile (".*;offset=([0-9]*)" );
42-
43- int page ;
44- int offset ;
45-
46- PageAndOffset (int page , int offset ) {
47- this .page = page ;
48- this .offset = offset ;
49- }
50-
51- int getPage () {
52- return page ;
53- }
54-
55- int getOffset () {
56- return offset ;
57- }
58-
59- public static PageAndOffset fromCursor (String cursor ) {
60- String s = decode (cursor );
61- Matcher matcher = pagePattern .matcher (s );
62- if (!matcher .find ()) {
63- throwInvalidCursor (s );
64- }
65- String page = matcher .group (1 );
66-
67- matcher = offsetPattern .matcher (s );
68- if (!matcher .find ()) {
69- throwInvalidCursor (s );
70- }
71- String offset = matcher .group (1 );
72- return new PageAndOffset (Integer .parseInt (page ), Integer .parseInt (offset ));
73- }
74-
75- ConnectionCursor toConnectionCursor () {
76- return new DefaultConnectionCursor (encode ("page=" + page + ";offset=" + offset ));
77- }
78-
79- private String encode (String s ) {
80- return encoder .encodeToString (s .getBytes (StandardCharsets .UTF_8 ));
81- }
82-
83- static private String decode (String s ) {
84- return new String (decoder .decode (s ), StandardCharsets .UTF_8 );
85- }
86-
87- private static void throwInvalidCursor (String cursor ) {
88- throw new IllegalArgumentException ("Invalid paged cursor provided : " + cursor );
89- }
90- }
91-
92- /**
93- * The results that come back from the page retrieval function need to tell us
94- * the list of results and the whether their is a next page or not
95- */
96- public static class PagedResult <T > {
97- private final List <T > results ;
98- private final boolean hasNextPage ;
99-
100- public PagedResult (List <T > results , boolean hasNextPage ) {
101- this .results = results ;
102- this .hasNextPage = hasNextPage ;
103- }
104-
105- public List <T > getResults () {
106- return results ;
107- }
108-
109- public boolean hasNextPage () {
110- return hasNextPage ;
111- }
112- }
113-
114-
11530 /**
11631 * Called to get a realy {@link graphql.relay.Connection} of edges where the underlying dataset
11732 * is a set of fixed size pages of data that can ONLY be read in a forward only manner
@@ -129,10 +44,10 @@ public static <T> Connection<T> getConnection(DataFetchingEnvironment env, int d
12944 throw new IllegalArgumentException ("You must provide a positive value for 'first'" );
13045 }
13146 boolean afterPresent = env .getArgument ("after" ) != null ;
132- String zeroZeroDefault = new PageAndOffset (0 , 0 ).toConnectionCursor ().toString ();
47+ String zeroZeroDefault = new CursorPageAndOffset (0 , 0 ).toConnectionCursor ().toString ();
13348 String afterCursor = getArg (env , "after" , zeroZeroDefault );
13449
135- PageAndOffset desiredPageAndOffset = PageAndOffset .fromCursor (afterCursor );
50+ CursorPageAndOffset desiredPageAndOffset = CursorPageAndOffset .fromCursor (afterCursor );
13651 int startPage = desiredPageAndOffset .getPage ();
13752
13853 List <Edge <T >> edges = new ArrayList <>();
@@ -144,7 +59,7 @@ public static <T> Connection<T> getConnection(DataFetchingEnvironment env, int d
14459
14560 PagedResult <T > pagedResult = pageOfDataRetriever .apply (startPage );
14661 for (T obj : pagedResult .getResults ()) {
147- ConnectionCursor edgeCursor = new PageAndOffset (startPage , fullOffset ).toConnectionCursor ();
62+ ConnectionCursor edgeCursor = new CursorPageAndOffset (startPage , fullOffset ).toConnectionCursor ();
14863 if (fullOffset == desiredPageAndOffset .getOffset ()) {
14964 addToEdges = true ;
15065 }
0 commit comments