42
42
import java .util .ArrayList ;
43
43
import java .util .Collection ;
44
44
import java .util .HashMap ;
45
- import java .util .HashSet ;
46
45
import java .util .Iterator ;
47
46
import java .util .LinkedHashMap ;
48
47
import java .util .List ;
49
48
import java .util .Map ;
50
49
import java .util .NoSuchElementException ;
51
- import java .util .Set ;
52
50
import java .util .regex .Matcher ;
53
51
import java .util .regex .Pattern ;
54
52
import java .util .zip .GZIPInputStream ;
@@ -330,104 +328,109 @@ private boolean isMethodWithBody() {
330
328
*
331
329
* Every iterator call reports a new batch.
332
330
*/
333
- /*package*/ <T > Iterator <T > asIterator (final String _tailApiUrl , final Class <T > type ) {
331
+ /*package*/ <T > PagingIterator <T > asIterator (String tailApiUrl , Class <T > type ) {
334
332
method ("GET" );
335
333
336
- final StringBuilder strBuilder = new StringBuilder (_tailApiUrl );
334
+ StringBuilder s = new StringBuilder (tailApiUrl );
337
335
if (!args .isEmpty ()) {
338
- boolean first = true ;
336
+ boolean first = true ;
339
337
try {
340
338
for (Entry a : args ) {
341
- strBuilder .append (first ? '?' : '&' );
339
+ s .append (first ? '?' : '&' );
342
340
first = false ;
343
- strBuilder .append (URLEncoder .encode (a .key , "UTF-8" ));
344
- strBuilder .append ('=' );
345
- strBuilder .append (URLEncoder .encode (a .value .toString (), "UTF-8" ));
341
+ s .append (URLEncoder .encode (a .key , "UTF-8" ));
342
+ s .append ('=' );
343
+ s .append (URLEncoder .encode (a .value .toString (), "UTF-8" ));
346
344
}
347
345
} catch (UnsupportedEncodingException e ) {
348
346
throw new AssertionError (e ); // UTF-8 is mandatory
349
347
}
350
348
}
351
349
352
- final String tailApiUrl = strBuilder .toString ();
350
+ try {
351
+ return new PagingIterator <T >(type , root .getApiURL (s .toString ()));
352
+ } catch (IOException e ) {
353
+ throw new Error (e );
354
+ }
355
+ }
353
356
354
- return new Iterator <T >() {
355
- /**
356
- * The next batch to be returned from {@link #next()}.
357
- */
358
- T next ;
359
- /**
360
- * URL of the next resource to be retrieved, or null if no more data is available.
361
- */
362
- URL url ;
357
+ class PagingIterator <T > implements Iterator <T > {
363
358
364
- {
365
- try {
366
- url = root .getApiURL (tailApiUrl );
367
- } catch (IOException e ) {
368
- throw new Error (e );
369
- }
370
- }
359
+ private final Class <T > type ;
371
360
372
- public boolean hasNext () {
373
- fetch ();
374
- return next != null ;
375
- }
361
+ /**
362
+ * The next batch to be returned from {@link #next()}.
363
+ */
364
+ private T next ;
376
365
377
- public T next () {
378
- fetch ();
379
- T r = next ;
380
- if (r ==null ) throw new NoSuchElementException ();
381
- next = null ;
382
- return r ;
383
- }
366
+ /**
367
+ * URL of the next resource to be retrieved, or null if no more data is available.
368
+ */
369
+ private URL url ;
384
370
385
- public void remove () {
386
- throw new UnsupportedOperationException ();
387
- }
371
+ PagingIterator (Class <T > type , URL url ) {
372
+ this .url = url ;
373
+ this .type = type ;
374
+ }
388
375
389
- private void fetch () {
390
- if (next !=null ) return ; // already fetched
391
- if (url ==null ) return ; // no more data to fetch
376
+ public boolean hasNext () {
377
+ fetch ();
378
+ return next !=null ;
379
+ }
392
380
393
- try {
394
- while (true ) {// loop while API rate limit is hit
395
- setupConnection (url );
396
- try {
397
- next = parse (type ,null );
398
- assert next !=null ;
399
- findNextURL ();
400
- return ;
401
- } catch (IOException e ) {
402
- handleApiError (e );
403
- }
404
- }
405
- } catch (IOException e ) {
406
- throw new Error (e );
407
- }
408
- }
381
+ public T next () {
382
+ fetch ();
383
+ T r = next ;
384
+ if (r ==null ) throw new NoSuchElementException ();
385
+ next = null ;
386
+ return r ;
387
+ }
409
388
410
- /**
411
- * Locate the next page from the pagination "Link" tag.
412
- */
413
- private void findNextURL () throws MalformedURLException {
414
- url = null ; // start defensively
415
- String link = uc .getHeaderField ("Link" );
416
- if (link ==null ) return ;
417
-
418
- for (String token : link .split (", " )) {
419
- if (token .endsWith ("rel=\" next\" " )) {
420
- // found the next page. This should look something like
421
- // <https://api.github.com/repos?page=3&per_page=100>; rel="next"
422
- int idx = token .indexOf ('>' );
423
- url = new URL (token .substring (1 ,idx ));
389
+ public void remove () {
390
+ throw new UnsupportedOperationException ();
391
+ }
392
+
393
+ private void fetch () {
394
+ if (next !=null ) return ; // already fetched
395
+ if (url ==null ) return ; // no more data to fetch
396
+
397
+ try {
398
+ while (true ) {// loop while API rate limit is hit
399
+ setupConnection (url );
400
+ try {
401
+ next = parse (type ,null );
402
+ assert next !=null ;
403
+ findNextURL ();
424
404
return ;
405
+ } catch (IOException e ) {
406
+ handleApiError (e );
425
407
}
426
408
}
409
+ } catch (IOException e ) {
410
+ throw new Error (e );
411
+ }
412
+ }
427
413
428
- // no more "next" link. we are done.
414
+ /**
415
+ * Locate the next page from the pagination "Link" tag.
416
+ */
417
+ private void findNextURL () throws MalformedURLException {
418
+ url = null ; // start defensively
419
+ String link = uc .getHeaderField ("Link" );
420
+ if (link ==null ) return ;
421
+
422
+ for (String token : link .split (", " )) {
423
+ if (token .endsWith ("rel=\" next\" " )) {
424
+ // found the next page. This should look something like
425
+ // <https://api.github.com/repos?page=3&per_page=100>; rel="next"
426
+ int idx = token .indexOf ('>' );
427
+ url = new URL (token .substring (1 ,idx ));
428
+ return ;
429
+ }
429
430
}
430
- };
431
+
432
+ // no more "next" link. we are done.
433
+ }
431
434
}
432
435
433
436
0 commit comments