11package io .apimatic .core ;
22
3+ import java .io .StringReader ;
4+ import java .util .regex .Matcher ;
5+ import java .util .regex .Pattern ;
6+ import javax .json .Json ;
7+ import javax .json .JsonException ;
8+ import javax .json .JsonPointer ;
9+ import javax .json .JsonReader ;
10+ import javax .json .JsonStructure ;
311import io .apimatic .core .types .CoreApiException ;
412import io .apimatic .coreinterfaces .http .Context ;
13+ import io .apimatic .coreinterfaces .http .HttpHeaders ;
14+ import io .apimatic .coreinterfaces .http .response .Response ;
515import io .apimatic .coreinterfaces .type .functional .ExceptionCreator ;
616
717/**
@@ -19,6 +29,11 @@ public final class ErrorCase<ExceptionType extends CoreApiException> {
1929 */
2030 private String reason ;
2131
32+ /**
33+ * Error message a template or not.
34+ */
35+ private boolean isErrorTemplate ;
36+
2237 /**
2338 * An instance of {@link ExceptionCreator}.
2439 */
@@ -28,10 +43,13 @@ public final class ErrorCase<ExceptionType extends CoreApiException> {
2843 * A private constructor.
2944 * @param reason the exception reason.
3045 * @param exceptionCreator the exceptionCreator.
46+ * @param isErrorTemplate error case for error template.
3147 */
32- private ErrorCase (final String reason , final ExceptionCreator <ExceptionType > exceptionCreator ) {
48+ private ErrorCase (final String reason , final ExceptionCreator <ExceptionType > exceptionCreator ,
49+ boolean isErrorTemplate ) {
3350 this .reason = reason ;
3451 this .exceptionCreator = exceptionCreator ;
52+ this .isErrorTemplate = isErrorTemplate ;
3553 }
3654
3755 /**
@@ -41,6 +59,9 @@ private ErrorCase(final String reason, final ExceptionCreator<ExceptionType> exc
4159 * @throws ExceptionType Represents error response from the server.
4260 */
4361 public void throwException (Context httpContext ) throws ExceptionType {
62+ if (isErrorTemplate ) {
63+ replacePlaceHolder (httpContext .getResponse ());
64+ }
4465 throw exceptionCreator .apply (reason , httpContext );
4566 }
4667
@@ -53,10 +74,120 @@ public void throwException(Context httpContext) throws ExceptionType {
5374 * thrown exception.
5475 * @return {@link ErrorCase}.
5576 */
56- public static <ExceptionType extends CoreApiException > ErrorCase <ExceptionType > create (
77+ public static <ExceptionType extends CoreApiException > ErrorCase <ExceptionType > setReason (
5778 String reason , ExceptionCreator <ExceptionType > exceptionCreator ) {
58- ErrorCase <ExceptionType > errorCase = new ErrorCase <ExceptionType >(reason , exceptionCreator );
79+ ErrorCase <ExceptionType > errorCase =
80+ new ErrorCase <ExceptionType >(reason , exceptionCreator , false );
5981 return errorCase ;
6082 }
6183
84+ /**
85+ * Create the errorcase using the error reason and exception creator functional interface which
86+ * throws the respective exception while throwing.
87+ * @param <ExceptionType> Represents error response from the server.
88+ * @param reason the exception message.
89+ * @param exceptionCreator the functional interface which is responsible to create the server
90+ * thrown exception.
91+ * @return {@link ErrorCase}.
92+ */
93+ public static <ExceptionType extends CoreApiException > ErrorCase <ExceptionType > setTemplate (
94+ String reason , ExceptionCreator <ExceptionType > exceptionCreator ) {
95+ return new ErrorCase <ExceptionType >(reason , exceptionCreator , true );
96+ }
97+
98+ private void replacePlaceHolder (Response response ) {
99+ replaceStatusCodeFromTemplate (response .getStatusCode ());
100+ replaceHeadersFromTemplate (response .getHeaders ());
101+ replaceBodyFromTemplate (response .getBody ());
102+ }
103+
104+ private void replaceHeadersFromTemplate (HttpHeaders headers ) {
105+ StringBuilder formatter = new StringBuilder (reason );
106+ Matcher matcher = Pattern .compile ("\\ {(.*?)\\ }" ).matcher (reason );
107+ while (matcher .find ()) {
108+ String key = matcher .group (1 );
109+ String pointerKey = key ;
110+ if (pointerKey .startsWith ("$response.header." )) {
111+ pointerKey = pointerKey .replace ("$response.header." , "" );
112+ String formatKey = String .format ("{%s}" , key );
113+ int index = formatter .indexOf (formatKey );
114+ pointerKey = pointerKey .toLowerCase ();
115+ if (index != -1 ) {
116+ formatter .replace (index , index + formatKey .length (),
117+ "" + (headers .has (pointerKey ) ? headers .value (pointerKey ) : "" ));
118+ }
119+ }
120+ }
121+ reason = formatter .toString ();
122+ }
123+
124+ private void replaceBodyFromTemplate (String responseBody ) {
125+ StringBuilder formatter = new StringBuilder (reason );
126+ JsonReader jsonReader = Json .createReader (new StringReader (responseBody ));
127+ JsonStructure jsonStructure = null ;
128+ try {
129+ jsonStructure = jsonReader .read ();
130+ } catch (Exception e ) {
131+ // No need to do anything here
132+ }
133+ jsonReader .close ();
134+ Matcher matcher = Pattern .compile ("\\ {(.*?)\\ }" ).matcher (reason );
135+ while (matcher .find ()) {
136+ String key = matcher .group (1 );
137+ String pointerKey = key ;
138+ replaceBodyString (responseBody , formatter , jsonStructure , key , pointerKey );
139+ }
140+ reason = formatter .toString ().replaceAll ("\" " , "" );
141+ }
142+
143+ private void replaceBodyString (String responseBody , StringBuilder formatter ,
144+ JsonStructure jsonStructure , String key , String pointerKey ) {
145+ if (pointerKey .startsWith ("$response.body" )) {
146+ String formatKey = String .format ("{%s}" , key );
147+ int index = formatter .indexOf (formatKey );
148+ String toReplaceString = "" ;
149+ toReplaceString = extractReplacementString (responseBody , jsonStructure , pointerKey ,
150+ toReplaceString );
151+ if (index != -1 ) {
152+ try {
153+
154+ formatter .replace (index , index + formatKey .length (), toReplaceString );
155+ } catch (JsonException ex ) {
156+ formatter .replace (index , index + formatKey .length (), "" );
157+ }
158+ }
159+ }
160+ }
161+
162+ private String extractReplacementString (String responseBody , JsonStructure jsonStructure ,
163+ String pointerKey , String toReplaceString ) {
164+ if (pointerKey .contains ("#" )) {
165+ pointerKey = pointerKey .replace ("$response.body#" , "" );
166+ JsonPointer jsonPointer = Json .createPointer (pointerKey );
167+ if (jsonStructure != null && jsonPointer .containsValue (jsonStructure )) {
168+ toReplaceString = jsonPointer .getValue (jsonStructure ).toString ();
169+ }
170+ } else {
171+ if (responseBody != null && !responseBody .isEmpty ()) {
172+ toReplaceString = responseBody ;
173+ }
174+ }
175+ return toReplaceString ;
176+ }
177+
178+ private void replaceStatusCodeFromTemplate (int statusCode ) {
179+ StringBuilder formatter = new StringBuilder (reason );
180+ Matcher matcher = Pattern .compile ("\\ {(.*?)\\ }" ).matcher (reason );
181+ while (matcher .find ()) {
182+ String key = matcher .group (1 );
183+ if (key .equals ("$statusCode" )) {
184+ String formatKey = String .format ("{%s}" , key );
185+ int index = formatter .indexOf (formatKey );
186+ if (index != -1 ) {
187+ formatter .replace (index , index + formatKey .length (), "" + statusCode );
188+ }
189+ }
190+ }
191+ reason = formatter .toString ();
192+ }
62193}
0 commit comments