2626import com .fasterxml .jackson .databind .JsonMappingException ;
2727import org .apache .commons .io .IOUtils ;
2828
29- import java .io .FileNotFoundException ;
30- import java .io .IOException ;
31- import java .io .InputStream ;
32- import java .io .InputStreamReader ;
33- import java .io .Reader ;
34- import java .io .UnsupportedEncodingException ;
29+ import java .io .*;
3530import java .lang .reflect .Array ;
3631import java .lang .reflect .Field ;
37- import java .net .HttpURLConnection ;
38- import java .net .MalformedURLException ;
39- import java .net .ProtocolException ;
40- import java .net .URL ;
41- import java .net .URLEncoder ;
42- import java .util .ArrayList ;
43- import java .util .Collection ;
44- import java .util .HashMap ;
45- import java .util .HashSet ;
46- import java .util .Iterator ;
47- import java .util .LinkedHashMap ;
48- import java .util .List ;
49- import java .util .Map ;
50- import java .util .NoSuchElementException ;
51- import java .util .Set ;
32+ import java .net .*;
33+ import java .util .*;
5234import java .util .regex .Matcher ;
5335import java .util .regex .Pattern ;
5436import java .util .zip .GZIPInputStream ;
5537
56- import static org .kohsuke .github .GitHub .* ;
38+ import static org .kohsuke .github .GitHub .MAPPER ;
5739
5840/**
5941 * A builder pattern for making HTTP call and parsing its output.
6345class Requester {
6446 private final GitHub root ;
6547 private final List <Entry > args = new ArrayList <Entry >();
66- private final Map <String ,String > headers = new LinkedHashMap <String , String >();
48+ private final Map <String , String > headers = new LinkedHashMap <String , String >();
6749
6850 /**
6951 * Request method.
@@ -97,7 +79,7 @@ private Entry(String key, Object value) {
9779 * If a header of the same name is already set, this method overrides it.
9880 */
9981 public void setHeader (String name , String value ) {
100- headers .put (name ,value );
82+ headers .put (name , value );
10183 }
10284
10385 /**
@@ -115,19 +97,19 @@ public Requester with(String key, int value) {
11597 }
11698
11799 public Requester with (String key , Integer value ) {
118- if (value != null )
100+ if (value != null )
119101 _with (key , value .intValue ());
120102 return this ;
121103 }
122104
123105 public Requester with (String key , boolean value ) {
124106 return _with (key , value );
125107 }
108+
126109 public Requester with (String key , Boolean value ) {
127110 return _with (key , value );
128111 }
129112
130-
131113 public Requester with (String key , String value ) {
132114 return _with (key , value );
133115 }
@@ -146,8 +128,8 @@ public Requester with(InputStream body) {
146128 }
147129
148130 public Requester _with (String key , Object value ) {
149- if (value != null ) {
150- args .add (new Entry (key ,value ));
131+ if (value != null ) {
132+ args .add (new Entry (key , value ));
151133 }
152134 return this ;
153135 }
@@ -162,7 +144,7 @@ public Requester set(String key, Object value) {
162144 return this ;
163145 }
164146 }
165- return _with (key ,value );
147+ return _with (key , value );
166148 }
167149
168150 public Requester method (String method ) {
@@ -176,7 +158,7 @@ public Requester contentType(String contentType) {
176158 }
177159
178160 public void to (String tailApiUrl ) throws IOException {
179- to (tailApiUrl ,null );
161+ to (tailApiUrl , null );
180162 }
181163
182164 /**
@@ -203,16 +185,16 @@ public <T> T to(String tailApiUrl, T existingInstance) throws IOException {
203185 */
204186 @ Deprecated
205187 public <T > T to (String tailApiUrl , Class <T > type , String method ) throws IOException {
206- return method (method ).to (tailApiUrl ,type );
188+ return method (method ).to (tailApiUrl , type );
207189 }
208190
209191 private <T > T _to (String tailApiUrl , Class <T > type , T instance ) throws IOException {
210192 while (true ) {// loop while API rate limit is hit
211193 if (method .equals ("GET" ) && !args .isEmpty ()) {
212- StringBuilder qs = new StringBuilder ();
194+ StringBuilder qs = new StringBuilder ();
213195 for (Entry arg : args ) {
214- qs .append (qs .length ()== 0 ? '?' : '&' );
215- qs .append (arg .key ).append ('=' ).append (URLEncoder .encode (arg .value .toString (),"UTF-8" ));
196+ qs .append (qs .length () == 0 ? '?' : '&' );
197+ qs .append (arg .key ).append ('=' ).append (URLEncoder .encode (arg .value .toString (), "UTF-8" ));
216198 }
217199 tailApiUrl += qs .toString ();
218200 }
@@ -282,7 +264,6 @@ public String getResponseHeader(String header) {
282264 return uc .getHeaderField (header );
283265 }
284266
285-
286267 /**
287268 * Set up the request parameters or POST payload.
288269 */
@@ -296,6 +277,7 @@ private void buildRequest() throws IOException {
296277 for (Entry e : args ) {
297278 json .put (e .key , e .value );
298279 }
280+ MAPPER .writeValue (uc .getOutputStream (), json );
299281 } else {
300282 try {
301283 byte [] bytes = new byte [32768 ];
@@ -311,8 +293,10 @@ private void buildRequest() throws IOException {
311293 }
312294
313295 private boolean isMethodWithBody () {
314- if (method .equals ("GET" )) return false ;
315- if (method .equals ("DELETE" )) return false ;
296+ if (method .equals ("GET" ))
297+ return false ;
298+ if (method .equals ("DELETE" ))
299+ return false ;
316300 return true ;
317301 }
318302
@@ -321,19 +305,19 @@ private boolean isMethodWithBody() {
321305 *
322306 * Every iterator call reports a new batch.
323307 */
324- /*package*/ <T > Iterator <T > asIterator (String _tailApiUrl , final Class <T > type ) {
308+ /* package */ <T > Iterator <T > asIterator (String _tailApiUrl , final Class <T > type ) {
325309 method ("GET" );
326310
327311 if (!args .isEmpty ()) {
328- boolean first = true ;
312+ boolean first = true ;
329313 try {
330314 for (Entry a : args ) {
331315 _tailApiUrl += first ? '?' : '&' ;
332316 first = false ;
333- _tailApiUrl += URLEncoder .encode (a .key ,"UTF-8" )+ '=' + URLEncoder .encode (a .value .toString (),"UTF-8" );
317+ _tailApiUrl += URLEncoder .encode (a .key , "UTF-8" ) + '=' + URLEncoder .encode (a .value .toString (), "UTF-8" );
334318 }
335319 } catch (UnsupportedEncodingException e ) {
336- throw new AssertionError (e ); // UTF-8 is mandatory
320+ throw new AssertionError (e ); // UTF-8 is mandatory
337321 }
338322 }
339323
@@ -359,13 +343,14 @@ private boolean isMethodWithBody() {
359343
360344 public boolean hasNext () {
361345 fetch ();
362- return next != null ;
346+ return next != null ;
363347 }
364348
365349 public T next () {
366350 fetch ();
367351 T r = next ;
368- if (r ==null ) throw new NoSuchElementException ();
352+ if (r == null )
353+ throw new NoSuchElementException ();
369354 next = null ;
370355 return r ;
371356 }
@@ -375,15 +360,17 @@ public void remove() {
375360 }
376361
377362 private void fetch () {
378- if (next !=null ) return ; // already fetched
379- if (url ==null ) return ; // no more data to fetch
363+ if (next != null )
364+ return ; // already fetched
365+ if (url == null )
366+ return ; // no more data to fetch
380367
381368 try {
382369 while (true ) {// loop while API rate limit is hit
383370 setupConnection (url );
384371 try {
385- next = parse (type ,null );
386- assert next != null ;
372+ next = parse (type , null );
373+ assert next != null ;
387374 findNextURL ();
388375 return ;
389376 } catch (IOException e ) {
@@ -401,14 +388,15 @@ private void fetch() {
401388 private void findNextURL () throws MalformedURLException {
402389 url = null ; // start defensively
403390 String link = uc .getHeaderField ("Link" );
404- if (link ==null ) return ;
391+ if (link == null )
392+ return ;
405393
406394 for (String token : link .split (", " )) {
407395 if (token .endsWith ("rel=\" next\" " )) {
408396 // found the next page. This should look something like
409397 // <https://api.github.com/repos?page=3&per_page=100>; rel="next"
410398 int idx = token .indexOf ('>' );
411- url = new URL (token .substring (1 ,idx ));
399+ url = new URL (token .substring (1 , idx ));
412400 return ;
413401 }
414402 }
@@ -418,18 +406,17 @@ private void findNextURL() throws MalformedURLException {
418406 };
419407 }
420408
421-
422409 private void setupConnection (URL url ) throws IOException {
423410 uc = root .getConnector ().connect (url );
424411
425412 // if the authentication is needed but no credential is given, try it anyway (so that some calls
426413 // that do work with anonymous access in the reduced form should still work.)
427- if (root .encodedAuthorization != null )
414+ if (root .encodedAuthorization != null )
428415 uc .setRequestProperty ("Authorization" , root .encodedAuthorization );
429416
430417 for (Map .Entry <String , String > e : headers .entrySet ()) {
431418 String v = e .getValue ();
432- if (v != null )
419+ if (v != null )
433420 uc .setRequestProperty (e .getKey (), v );
434421 }
435422
@@ -440,28 +427,28 @@ private void setupConnection(URL url) throws IOException {
440427 try {
441428 Field $method = HttpURLConnection .class .getDeclaredField ("method" );
442429 $method .setAccessible (true );
443- $method .set (uc ,method );
430+ $method .set (uc , method );
444431 } catch (Exception x ) {
445- throw (IOException )new IOException ("Failed to set the custom verb" ).initCause (x );
432+ throw (IOException ) new IOException ("Failed to set the custom verb" ).initCause (x );
446433 }
447434 }
448435 uc .setRequestProperty ("Accept-Encoding" , "gzip" );
449436 }
450437
451438 private <T > T parse (Class <T > type , T instance ) throws IOException {
452- if (uc .getResponseCode ()== 304 )
453- return null ; // special case handling for 304 unmodified, as the content will be ""
439+ if (uc .getResponseCode () == 304 )
440+ return null ; // special case handling for 304 unmodified, as the content will be ""
454441 InputStreamReader r = null ;
455442 try {
456443 r = new InputStreamReader (wrapStream (uc .getInputStream ()), "UTF-8" );
457444 String data = IOUtils .toString (r );
458- if (type != null )
445+ if (type != null )
459446 try {
460- return MAPPER .readValue (data ,type );
447+ return MAPPER .readValue (data , type );
461448 } catch (JsonMappingException e ) {
462- throw (IOException )new IOException ("Failed to deserialize " + data ).initCause (e );
449+ throw (IOException ) new IOException ("Failed to deserialize " + data ).initCause (e );
463450 }
464- if (instance != null )
451+ if (instance != null )
465452 return MAPPER .readerForUpdating (instance ).<T >readValue (data );
466453 return null ;
467454 } finally {
@@ -474,33 +461,33 @@ private <T> T parse(Class<T> type, T instance) throws IOException {
474461 */
475462 private InputStream wrapStream (InputStream in ) throws IOException {
476463 String encoding = uc .getContentEncoding ();
477- if (encoding ==null || in ==null ) return in ;
478- if (encoding .equals ("gzip" )) return new GZIPInputStream (in );
464+ if (encoding == null || in == null )
465+ return in ;
466+ if (encoding .equals ("gzip" ))
467+ return new GZIPInputStream (in );
479468
480- throw new UnsupportedOperationException ("Unexpected Content-Encoding: " + encoding );
469+ throw new UnsupportedOperationException ("Unexpected Content-Encoding: " + encoding );
481470 }
482471
483472 /**
484473 * Handle API error by either throwing it or by returning normally to retry.
485474 */
486- /*package*/ void handleApiError (IOException e ) throws IOException {
475+ /* package */ void handleApiError (IOException e ) throws IOException {
487476 if (uc .getResponseCode () == 401 ) // Unauthorized == bad creds
488477 throw e ;
489478
490479 if ("0" .equals (uc .getHeaderField ("X-RateLimit-Remaining" ))) {
491- root .rateLimitHandler .onError (e ,uc );
480+ root .rateLimitHandler .onError (e , uc );
492481 }
493482
494483 InputStream es = wrapStream (uc .getErrorStream ());
495484 try {
496- if (es != null ) {
485+ if (es != null ) {
497486 if (e instanceof FileNotFoundException ) {
498487 // pass through 404 Not Found to allow the caller to handle it intelligently
499488 throw (IOException ) new FileNotFoundException (IOUtils .toString (es , "UTF-8" )).initCause (e );
500- } else
501- throw (IOException ) new IOException (IOUtils .toString (es , "UTF-8" )).initCause (e );
502- } else
503- throw e ;
489+ } else throw (IOException ) new IOException (IOUtils .toString (es , "UTF-8" )).initCause (e );
490+ } else throw e ;
504491 } finally {
505492 IOUtils .closeQuietly (es );
506493 }
0 commit comments