11/*
2- * Copyright 2017 Basis Technology Corp.
2+ * Copyright 2017-2022 Basis Technology Corp.
33*
44* Licensed under the Apache License, Version 2.0 (the "License");
55* you may not use this file except in compliance with the License.
7373import java .util .Properties ;
7474import java .util .Set ;
7575import java .util .concurrent .Future ;
76+ import java .util .regex .Pattern ;
7677import java .util .zip .GZIPInputStream ;
7778
7879import static java .net .HttpURLConnection .HTTP_OK ;
@@ -85,8 +86,11 @@ public class HttpRosetteAPI extends AbstractRosetteAPI {
8586 public static final String DEFAULT_URL_BASE = "https://api.rosette.com/rest/v1" ;
8687 public static final String SERVICE_NAME = "RosetteAPI" ;
8788 public static final String BINDING_VERSION = getVersion ();
88- public static final String USER_AGENT_STR = SERVICE_NAME + "-Java/" + BINDING_VERSION + "/" + System .getProperty ("java.version" );
89+ public static final String USER_AGENT_STR = SERVICE_NAME + "-Java/" + BINDING_VERSION + "/"
90+ + System .getProperty ("java.version" );
8991 private static final Logger LOG = LoggerFactory .getLogger (HttpRosetteAPI .class );
92+ private static final String IO_EXCEPTION_MESSAGE = "IO Exception communicating with the Rosette API" ;
93+ private static final Pattern TRAILING_SLASHES = Pattern .compile ("/+$" );
9094 private String urlBase = DEFAULT_URL_BASE ;
9195 private int failureRetries = 1 ;
9296 private ObjectMapper mapper ;
@@ -116,7 +120,7 @@ private HttpRosetteAPI() {
116120 HttpRosetteAPI (String key , String urlToCall , Integer failureRetries ,
117121 CloseableHttpClient httpClient , List <Header > additionalHeaders ,
118122 Integer connectionConcurrency , boolean onlyAcceptKnownFields ) throws HttpRosetteAPIException {
119- urlBase = urlToCall == null ? urlBase : urlToCall .trim ().replaceAll ("/+$" , "" );
123+ urlBase = urlToCall == null ? urlBase : TRAILING_SLASHES . matcher ( urlToCall .trim ()) .replaceAll ("" );
120124 if (failureRetries != null && failureRetries >= 1 ) {
121125 this .failureRetries = failureRetries ;
122126 }
@@ -241,7 +245,8 @@ public PingResponse ping() throws IOException, HttpRosetteAPIException {
241245 @ Override
242246 public SupportedLanguagesResponse getSupportedLanguages (String endpoint ) throws HttpRosetteAPIException {
243247 if (DOC_ENDPOINTS .contains (endpoint ) || NAME_DEDUPLICATION_SERVICE_PATH .equals (endpoint )) {
244- return sendGetRequest (urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH , SupportedLanguagesResponse .class );
248+ return sendGetRequest (urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH ,
249+ SupportedLanguagesResponse .class );
245250 } else {
246251 return null ;
247252 }
@@ -258,7 +263,8 @@ public SupportedLanguagesResponse getSupportedLanguages(String endpoint) throws
258263 @ Override
259264 public SupportedLanguagePairsResponse getSupportedLanguagePairs (String endpoint ) throws HttpRosetteAPIException {
260265 if (NAMES_ENDPOINTS .contains (endpoint ) && !NAME_DEDUPLICATION_SERVICE_PATH .equals (endpoint )) {
261- return sendGetRequest (urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH , SupportedLanguagePairsResponse .class );
266+ return sendGetRequest (urlBase + endpoint + SUPPORTED_LANGUAGES_SUBPATH ,
267+ SupportedLanguagePairsResponse .class );
262268 } else {
263269 return null ;
264270 }
@@ -276,11 +282,12 @@ public SupportedLanguagePairsResponse getSupportedLanguagePairs(String endpoint)
276282 * @throws RosetteRuntimeException for other errors, such as communications problems with HTTP.
277283 */
278284 @ Override
279- public <RequestType extends Request , ResponseType extends Response > ResponseType perform (String endpoint , RequestType request , Class <ResponseType > responseClass ) throws HttpRosetteAPIException {
285+ public <RequestType extends Request , ResponseType extends Response > ResponseType perform (String endpoint ,
286+ RequestType request , Class <ResponseType > responseClass ) throws HttpRosetteAPIException {
280287 try {
281288 return sendPostRequest (request , urlBase + endpoint , responseClass );
282289 } catch (IOException e ) {
283- throw new RosetteRuntimeException ("IO Exception communicating with the Rosette API" , e );
290+ throw new RosetteRuntimeException (IO_EXCEPTION_MESSAGE , e );
284291 } catch (URISyntaxException e ) {
285292 throw new RosetteRuntimeException ("Invalid URI" , e );
286293 }
@@ -296,11 +303,12 @@ public <RequestType extends Request, ResponseType extends Response> ResponseType
296303 * @throws RosetteRuntimeException for other errors, such as communications problems with HTTP.
297304 */
298305 @ Override
299- public <RequestType extends Request > AnnotatedText perform (String endpoint , RequestType request ) throws HttpRosetteAPIException {
306+ public <RequestType extends Request > AnnotatedText perform (String endpoint , RequestType request )
307+ throws HttpRosetteAPIException {
300308 try {
301309 return sendPostRequest (request , urlBase + endpoint , AnnotatedText .class );
302310 } catch (IOException e ) {
303- throw new RosetteRuntimeException ("IO Exception communicating with the Rosette API" , e );
311+ throw new RosetteRuntimeException (IO_EXCEPTION_MESSAGE , e );
304312 } catch (URISyntaxException e ) {
305313 throw new RosetteRuntimeException ("Invalid URI" , e );
306314 }
@@ -310,7 +318,9 @@ public <RequestType extends Request> AnnotatedText perform(String endpoint, Requ
310318 * This method always throws UnsupportedOperationException.
311319 */
312320 @ Override
313- public <RequestType extends Request , ResponseType extends Response > Future <ResponseType > performAsync (String endpoint , RequestType request , Class <ResponseType > responseClass ) throws HttpRosetteAPIException {
321+ public <RequestType extends Request , ResponseType extends Response > Future <ResponseType >
322+ performAsync (String endpoint , RequestType request , Class <ResponseType > responseClass )
323+ throws HttpRosetteAPIException {
314324 throw new UnsupportedOperationException ("Asynchronous operations are not yet supported" );
315325 }
316326
@@ -335,7 +345,7 @@ private <T extends Response> T sendGetRequest(String urlStr, Class<T> clazz) thr
335345 responseHeadersToExtendedInformation (resp , httpResponse );
336346 return resp ;
337347 } catch (IOException e ) {
338- throw new RosetteRuntimeException ("IO Exception communicating with the Rosette API" , e );
348+ throw new RosetteRuntimeException (IO_EXCEPTION_MESSAGE , e );
339349 }
340350 }
341351
@@ -349,7 +359,8 @@ private <T extends Response> T sendGetRequest(String urlStr, Class<T> clazz) thr
349359 * @return Response
350360 * @throws IOException
351361 */
352- private <T > T sendPostRequest (Object request , String urlStr , Class <T > clazz ) throws IOException , URISyntaxException {
362+ private <T > T sendPostRequest (Object request , String urlStr , Class <T > clazz )
363+ throws IOException , URISyntaxException {
353364 ObjectWriter writer = mapper .writer ().without (JsonGenerator .Feature .AUTO_CLOSE_TARGET );
354365 boolean notPlainText = false ;
355366 if (request instanceof DocumentRequest ) {
@@ -391,7 +402,7 @@ private <T> T sendPostRequest(Object request, String urlStr, Class<T> clazz) thr
391402 T resp = getResponse (response , clazz );
392403 Header ridHeader = response .getFirstHeader ("X-RosetteAPI-DocumentRequest-Id" );
393404 if (ridHeader != null && ridHeader .getValue () != null ) {
394- LOG .debug ("DocumentRequest ID " + ridHeader .getValue ());
405+ LOG .debug ("DocumentRequest ID {}" , ridHeader .getValue ());
395406 }
396407 if (resp instanceof Response ) {
397408 responseHeadersToExtendedInformation ((Response )resp , response );
@@ -418,7 +429,8 @@ private <T extends Response> void responseHeadersToExtendedInformation(T resp, H
418429 if (resp .getExtendedInformation ().get (header .getName ()) instanceof Set ) {
419430 currentSetValue = (Set <Object >) resp .getExtendedInformation ().get (header .getName ());
420431 } else {
421- currentSetValue = new HashSet <>(Collections .singletonList (resp .getExtendedInformation ().get (header .getName ())));
432+ currentSetValue = new HashSet <>(Collections .singletonList (resp
433+ .getExtendedInformation ().get (header .getName ())));
422434 }
423435 currentSetValue .add (header .getValue ());
424436 resp .addExtendedInformation (header .getName (), currentSetValue );
@@ -459,7 +471,8 @@ public boolean isStreaming() {
459471 });
460472 }
461473
462- private void setupMultipartRequest (final Request request , final ObjectWriter finalWriter , HttpPost post ) throws IOException {
474+ private void setupMultipartRequest (final Request request , final ObjectWriter finalWriter , HttpPost post )
475+ throws IOException {
463476 MultipartEntityBuilder builder = MultipartEntityBuilder .create ();
464477 builder .setMimeSubtype ("mixed" );
465478 builder .setMode (HttpMultipartMode .STRICT );
@@ -533,7 +546,8 @@ private String headerValueOrNull(Header header) {
533546 * @return Response
534547 * @throws IOException
535548 */
536- private <T extends Object > T getResponse (HttpResponse httpResponse , Class <T > clazz ) throws IOException , HttpRosetteAPIException {
549+ private <T extends Object > T getResponse (HttpResponse httpResponse , Class <T > clazz )
550+ throws IOException , HttpRosetteAPIException {
537551 int status = httpResponse .getStatusLine ().getStatusCode ();
538552 String encoding = headerValueOrNull (httpResponse .getFirstHeader (HttpHeaders .CONTENT_ENCODING ));
539553
@@ -548,15 +562,16 @@ private <T extends Object> T getResponse(HttpResponse httpResponse, Class<T> cla
548562 if ("application/json" .equals (responseContentType )) {
549563 ErrorResponse errorResponse = mapper .readValue (inputStream , ErrorResponse .class );
550564 if (ridHeader != null ) {
551- LOG .debug ("DocumentRequest ID " + ridHeader );
565+ LOG .debug ("DocumentRequest ID {}" , ridHeader );
552566 }
553567 if (ecHeader != null ) {
554568 errorResponse .setCode (ecHeader );
555569 }
556570 if (429 == status ) {
557571 String concurrencyMessage = "You have exceeded your plan's limit on concurrent calls. "
558- + "This could be caused by multiple processes or threads making Rosette API calls in parallel, "
559- + "or if your httpClient is configured with higher concurrency than your plan allows." ;
572+ + "This could be caused by multiple processes or threads making Rosette API calls "
573+ + "in parallel, or if your httpClient is configured with higher concurrency "
574+ + "than your plan allows." ;
560575 if (emHeader == null ) {
561576 emHeader = concurrencyMessage ;
562577 } else {
@@ -677,6 +692,7 @@ public Builder additionalHeader(String name, String value) {
677692 * Only process the response from server if all fields are recognized. If set and a new
678693 * field is returned in the response, exception will be thrown.
679694 *
695+ * @param onlyAcceptKnownFields whether to accept known fields.
680696 * @return this.
681697 */
682698 public Builder onlyAcceptKnownFields (boolean onlyAcceptKnownFields ) {
0 commit comments