Last active
March 26, 2021 19:49
-
-
Save medkhelifi/ee4f7196e1319f807460d8ec9674a724 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.medkhelifi.api; | |
import com.medkhelifi.exceptions.enums.ApiErrNumber; | |
import com.medkhelifi.api.error.ApiError; | |
import com.medkhelifi.api.error.ApiValidationError; | |
import com.medkhelifi.api.error.sub.ApiSubError; | |
import com.medkhelifi.exceptions.ApiException; | |
import com.medkhelifi.api.success.ApiSuccess; | |
import com.medkhelifi.api.success.ApiSuccessType; | |
import com.medkhelifi.util.Util; | |
import lombok.Getter; | |
import org.springframework.http.HttpStatus; | |
import org.springframework.http.ResponseEntity; | |
import javax.servlet.http.HttpServletResponse; | |
import java.io.IOException; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.List; | |
import java.util.Objects; | |
/** | |
* Extension of {@link ResponseEntity} that use {@link Api} to represent the HTTP response. | |
* CustomResponseEntity use builder design pattern ({@link CustomResponseEntityBuilder}) to construct the {@link Api} response. | |
* | |
* <code> | |
* return new CustomResponseEntity.CustomResponseEntityBuilder(OK) | |
* .data("Hello World") | |
* .build(); | |
* </code> | |
* <p> | |
* The constructor is private, the only way to instantiate it, is to go through the static nested {@link CustomResponseEntityBuilder} class | |
* </p> | |
* | |
* @param <T> the body type | |
* @author medKhelifi | |
* @since 0.1.0 | |
*/ | |
public class CustomResponseEntity<T extends Api> extends ResponseEntity<T> { | |
/** | |
* Instantiates a new Custom response entity through {@link CustomResponseEntityBuilder}. | |
* | |
* @param customResponseEntityBuilder the custom response entity builder | |
*/ | |
private CustomResponseEntity(CustomResponseEntityBuilder<T> customResponseEntityBuilder){ | |
super(customResponseEntityBuilder.getApi(), customResponseEntityBuilder.api.getHttpStatus()); | |
} | |
/** | |
* The Custom response entity builder. | |
* | |
* @param <U> the type parameter | |
*/ | |
public static class CustomResponseEntityBuilder<U extends Api>{ | |
@Getter | |
private U api; | |
/** | |
* Instantiates a new Custom response entity builder. | |
* | |
* @param cls the cls | |
* @param status the status | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder(Class<U> cls, HttpStatus status) throws ApiException { | |
try { | |
this.api = cls.getDeclaredConstructor(HttpStatus.class).newInstance(status); | |
} catch (NullPointerException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { | |
throw new ApiException(ApiErrNumber.API_0001, e); | |
} | |
} | |
/** | |
* Debug message custom response entity builder. | |
* | |
* @param ex the ex | |
* @return the custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> debugMessage(Throwable ex) throws ApiException { | |
this.validateApi(); | |
try{ | |
( (ApiError ) this.api).setDebugMessage(ex.getCause()!=null? ex.getCause().getMessage(): ex.getLocalizedMessage()); | |
}catch (Exception castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* Message custom response entity builder. | |
* | |
* @param message the message | |
* @return the custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> message(java.lang.String message) throws ApiException { | |
this.validateApi(); | |
this.api.setMessage(message); | |
return this; | |
} | |
/** | |
* Err number custom response entity builder. | |
* | |
* @param apiErrNumber the Api error number | |
* @return CustomResponseEntityBuilder custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> errNumber(String apiErrNumber) throws ApiException { | |
this.validateApi(); | |
try{ | |
( (ApiError) this.api).setErrNumber(apiErrNumber); | |
}catch (ClassCastException castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* Define the api success {@link ApiSuccessType} | |
* | |
* @param type the type of success response | |
* @return the custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> type (ApiSuccessType type) throws ApiException { | |
this.validateApi(); | |
try{ | |
((ApiSuccess) this.api).setType(type); | |
}catch (ClassCastException castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* Data custom response entity builder. | |
* | |
* @param data the data | |
* @return the custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> data (Object data) throws ApiException { | |
this.validateApi(); | |
try{ | |
((ApiSuccess) this.api).setData(data); | |
}catch (ClassCastException castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* Items list custom response entity builder | |
* | |
* @param items the list of items | |
* @return the custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> items (List<Object> items) throws ApiException { | |
this.validateApi(); | |
try{ | |
((ApiSuccess) this.api).setItems(items); | |
}catch (ClassCastException castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* Add sub error custom response entity builder. | |
* | |
* @param apiSubError the api sub error | |
* @return custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> addSubError(ApiSubError apiSubError) throws ApiException { | |
this.validateApi(); | |
try{ | |
((ApiValidationError) this.api).addValidationError(apiSubError); | |
}catch (ClassCastException castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* Sub error custom response entity builder. | |
* | |
* @param apiSubErrors the api sub errors | |
* @return the custom response entity builder | |
* @throws ApiException the api exception | |
*/ | |
public CustomResponseEntityBuilder<U> subError(List<ApiSubError> apiSubErrors) throws ApiException { | |
this.validateApi(); | |
try{ | |
((ApiValidationError) this.api).setSubErrors(apiSubErrors); | |
}catch (ClassCastException castEx){ | |
throw new ApiException(ApiErrNumber.API_0002, castEx); | |
} | |
return this; | |
} | |
/** | |
* check the {@link Api} instance if it's valid | |
*/ | |
private void validateApi() throws ApiException { | |
if(this.api == null ) | |
throw new ApiException(ApiErrNumber.API_0003); | |
} | |
/** | |
* Return the final constructed {@link CustomResponseEntity} | |
* | |
* @return CustomResponseEntity custom response entity | |
*/ | |
public CustomResponseEntity<U> build(){ | |
return new CustomResponseEntity<>(this); | |
} | |
} | |
/** | |
* Write the {@link HttpServletResponse} response by passing the CustomResponseEntity {@link Api} | |
* | |
* @param res The {@link HttpServletResponse } | |
* @throws IOException Throw {@link IOException} if some problem occurred when {@link HttpServletResponse} writer. | |
*/ | |
public void responseWriter(HttpServletResponse res) throws IOException { | |
res.setStatus(this.getStatusCode().value()); | |
res.setContentType("application/json"); | |
res.getWriter().write(Objects.requireNonNull(Util.convertObjectToJson((this.getBody()) ))); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment