All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.captaingoldfish.scim.sdk.client.builder.ListBuilder Maven / Gradle / Ivy

There is a newer version: 1.26.0
Show newest version
// Generated by delombok at Sat Oct 07 17:30:34 CEST 2023
package de.captaingoldfish.scim.sdk.client.builder;

import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import de.captaingoldfish.scim.sdk.common.utils.EncodingUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import de.captaingoldfish.scim.sdk.client.ScimClientConfig;
import de.captaingoldfish.scim.sdk.client.http.HttpResponse;
import de.captaingoldfish.scim.sdk.client.http.ScimHttpClient;
import de.captaingoldfish.scim.sdk.client.response.ServerResponse;
import de.captaingoldfish.scim.sdk.common.constants.AttributeNames;
import de.captaingoldfish.scim.sdk.common.constants.HttpStatus;
import de.captaingoldfish.scim.sdk.common.constants.SchemaUris;
import de.captaingoldfish.scim.sdk.common.constants.enums.Comparator;
import de.captaingoldfish.scim.sdk.common.constants.enums.SortOrder;
import de.captaingoldfish.scim.sdk.common.request.SearchRequest;
import de.captaingoldfish.scim.sdk.common.resources.ResourceNode;
import de.captaingoldfish.scim.sdk.common.resources.base.ScimObjectNode;
import de.captaingoldfish.scim.sdk.common.response.ListResponse;
import de.captaingoldfish.scim.sdk.common.utils.JsonHelper;


/**
 * author Pascal Knueppel 
* created at: 16.12.2019 - 13:00
*
* a builder that can be used to build a list request */ public class ListBuilder { /** * the base url of the scim provider */ private final String baseUrl; /** * the endpoint path of the resource e.g. /Users or /Groups */ private final String endpoint; /** * the entity type that should be returned. Has actually no usage but is only here to setup the generic type * of this instance */ private final Class responseEntityType; /** * the parameters that will be used for the list request */ private final Map requestParameters = new HashMap<>(); /** * an apache http client wrapper that offers some convenience methods */ private final ScimHttpClient scimHttpClient; /** * the fully qualified url to the required resource */ private final String fullUrl; /** * if the resource should be retrieved by using the fully qualified url * * @param fullUrl the fully qualified url to the required resource * @param responseEntityType the type of the resource that should be returned * @param scimHttpClient the http client instance */ public ListBuilder(String fullUrl, Class responseEntityType, ScimHttpClient scimHttpClient) { this.baseUrl = null; this.endpoint = null; this.responseEntityType = responseEntityType; this.scimHttpClient = scimHttpClient; this.fullUrl = fullUrl; } public ListBuilder(String baseUrl, String endpoint, Class responseEntityType, ScimHttpClient scimHttpClient) { this.baseUrl = baseUrl; this.endpoint = endpoint; this.responseEntityType = responseEntityType; this.scimHttpClient = scimHttpClient; this.fullUrl = null; } /** * sets the count parameter for the maximum number of entries that should be returned * * @param count the maximum number of entries that should be returned */ public ListBuilder count(int count) { requestParameters.put(AttributeNames.RFC7643.COUNT, String.valueOf(count)); return this; } /** * sets the startIndex parameter for the first entry that should be returned * * @param startIndex the start index from which the entries should be returned */ public ListBuilder startIndex(long startIndex) { requestParameters.put(AttributeNames.RFC7643.START_INDEX, String.valueOf(startIndex)); return this; } /** * sets the attribute name that should be used for sorting the entries * * @param sortBy the attribute name that should be used for sorting the entries */ public ListBuilder sortBy(String sortBy) { requestParameters.put(AttributeNames.RFC7643.SORT_BY, sortBy); return this; } /** * sets the sorting order of the resources * * @param sortOrder the sorting order of the resources */ public ListBuilder sortOrder(SortOrder sortOrder) { requestParameters.put(AttributeNames.RFC7643.SORT_ORDER, sortOrder.name().toLowerCase()); return this; } /** * adds the attributes that should be returned by the service provider * * @param attributeNames the names of the attributes that should be returned by the service provider */ public ListBuilder attributes(String... attributeNames) { if (attributeNames != null) { requestParameters.put(AttributeNames.RFC7643.ATTRIBUTES, String.join(",", attributeNames)); } return this; } /** * adds the excluded attributes that should not be returned by the service provider * * @param attributeNames the names of the excluded attributes that should not be returned by the service * provider */ public ListBuilder excludedAttributes(String... attributeNames) { if (attributeNames != null) { requestParameters.put(AttributeNames.RFC7643.EXCLUDED_ATTRIBUTES, String.join(",", attributeNames)); } return this; } /** * creates a new filter-builder that can be used to create filter expressions */ public FilterBuilder filter(String attributeName, Comparator comparator, String value) { return filter(false, attributeName, comparator, value); } /** * creates a new filter-builder that can be used to create filter expressions */ public FilterBuilder filter(boolean openParanthesis, String attributeName, Comparator comparator, String value) { return new FilterBuilder<>(this, attributeName, comparator, value, openParanthesis); } /** * sets the given filter as attribute */ public ListBuilder filter(String filter) { requestParameters.put(AttributeNames.RFC7643.FILTER, filter); return this; } /** * adds additional custom parameters to the request that are unknown by the SCIM specification * * @param attributeName the name of the attribute to add * @param attribute the value of the attribute to add */ public ListBuilder custom(String attributeName, String attribute) { requestParameters.put(attributeName, attribute); return this; } /** * list requests can be either send with a get-request or a post request * * @return a get-request builder */ public GetRequestBuilder get() { return new GetRequestBuilder<>(this); } /** * list requests can be either send with a get-request or a post request * * @return a post-request builder */ public PostRequestBuilder post() { return new PostRequestBuilder<>(this); } /** * a request builder that builds the list-request as a http-get request */ public static class GetRequestBuilder extends RequestBuilder> { /** * the original list builder instance */ private ListBuilder listBuilder; public GetRequestBuilder(ListBuilder listBuilder) { super(listBuilder.baseUrl, listBuilder.endpoint, (Class>)new ListResponse().getClass(), listBuilder.scimHttpClient); this.listBuilder = listBuilder; } /** * {@inheritDoc} */ @Override public GetRequestBuilder setExpectedResponseHeaders(Map requiredResponseHeaders) { return (GetRequestBuilder)super.setExpectedResponseHeaders(requiredResponseHeaders); } /** * {@inheritDoc} */ @Override protected boolean isExpectedResponseCode(int httpStatus) { return HttpStatus.OK == httpStatus; } /** * {@inheritDoc} */ @Override protected HttpUriRequest getHttpUriRequest() { StringBuilder queryBuilder = new StringBuilder(); if (!listBuilder.requestParameters.isEmpty()) { if (StringUtils.contains(listBuilder.fullUrl, "?")) { queryBuilder.append("&"); } else { queryBuilder.append("?"); } List pairs = new ArrayList<>(); listBuilder.requestParameters.forEach((key, value) -> { pairs.add(key + "=" + EncodingUtils.urlEncode(value)); }); queryBuilder.append(String.join("&", pairs)); } HttpGet httpGet; if (StringUtils.isBlank(listBuilder.fullUrl)) { httpGet = new HttpGet(getBaseUrl() + getEndpoint() + queryBuilder.toString()); } else { httpGet = new HttpGet(listBuilder.fullUrl + queryBuilder.toString()); } return httpGet; } /** * checks if the response contains a schema-uri that matches the value of * {@link de.captaingoldfish.scim.sdk.common.constants.SchemaUris#LIST_RESPONSE_URI} */ @Override protected Function isResponseParseable() { return httpResponse -> { String responseBody = httpResponse.getResponseBody(); if (StringUtils.isNotBlank(responseBody) && responseBody.contains(SchemaUris.LIST_RESPONSE_URI)) { return true; } return false; }; } /** * uses a custom response type that overrides the translation of the returned resource */ @Override protected ServerResponse> toResponse(HttpResponse response) { return new ListServerResponse<>(response, isExpectedResponseCode(response.getHttpStatusCode()), getResponseEntityType(), listBuilder.responseEntityType, isResponseParseable(), getRequiredResponseHeaders()); } } /** * a request builder that builds the list-request as a http-post request */ public static class PostRequestBuilder extends RequestBuilder> { /** * the original list builder instance */ private ListBuilder listBuilder; public PostRequestBuilder(ListBuilder listBuilder) { super(listBuilder.baseUrl, listBuilder.endpoint, (Class>)new ListResponse().getClass(), listBuilder.scimHttpClient); this.listBuilder = listBuilder; } /** * {@inheritDoc} */ @Override public PostRequestBuilder setExpectedResponseHeaders(Map requiredResponseHeaders) { return (PostRequestBuilder)super.setExpectedResponseHeaders(requiredResponseHeaders); } /** * {@inheritDoc} */ @Override protected boolean isExpectedResponseCode(int httpStatus) { return HttpStatus.OK == httpStatus; } /** * {@inheritDoc} */ @Override protected HttpUriRequest getHttpUriRequest() { HttpPost httpPost; if (StringUtils.isBlank(listBuilder.fullUrl)) { httpPost = new HttpPost(getBaseUrl() + getEndpoint() + "/.search"); } else { String url = listBuilder.fullUrl; if (url.endsWith("/.search")) { httpPost = new HttpPost(listBuilder.fullUrl); } else { httpPost = new HttpPost(listBuilder.fullUrl + "/.search"); } } if (!listBuilder.requestParameters.isEmpty()) { SearchRequest searchRequest = SearchRequest.builder().build(); listBuilder.requestParameters.forEach(searchRequest::put); super.setResource(searchRequest); StringEntity stringEntity = new StringEntity(getResource(), StandardCharsets.UTF_8); httpPost.setEntity(stringEntity); } return httpPost; } /** * checks if the response contains a schema-uri that matches the value of * {@link de.captaingoldfish.scim.sdk.common.constants.SchemaUris#LIST_RESPONSE_URI} */ @Override protected Function isResponseParseable() { return httpResponse -> { String responseBody = httpResponse.getResponseBody(); if (StringUtils.isNotBlank(responseBody) && responseBody.contains(SchemaUris.LIST_RESPONSE_URI)) { return true; } return false; }; } /** * uses a custom response type that overrides the translation of the returned resource */ @Override protected ServerResponse> toResponse(HttpResponse response) { return new ListServerResponse<>(response, isExpectedResponseCode(response.getHttpStatusCode()), getResponseEntityType(), listBuilder.responseEntityType, isResponseParseable(), getRequiredResponseHeaders()); } } /** * overrides the translation of the returned resource from the server */ public static class ListServerResponse extends ServerResponse> { /** * the generic type of the resources within the list response */ private Class responseEntityType; public ListServerResponse(HttpResponse httpResponse, boolean expectedResponseCode, Class> type, Class responseEntityType, Function isResponseParseable, Map requiredResponseHeaders) { super(httpResponse, expectedResponseCode, type, isResponseParseable, requiredResponseHeaders); this.responseEntityType = responseEntityType; } /** * translates the response body into a list response and parses then all json nodes within the resource into * objects of the given resource node type * * @param responseType the type of the node which might be of type * {@link de.captaingoldfish.scim.sdk.common.resources.User}, * {@link de.captaingoldfish.scim.sdk.common.resources.Group} * @return a list response with resources of type R */ @Override public R getResource(Class responseType) { ListResponse listResponse = JsonHelper.readJsonDocument(getResponseBody(), ListResponse.class); List typedResources = listResponse.getListedResources().parallelStream().map(scimObjectNode -> { return JsonHelper.readJsonDocument(scimObjectNode.toString(), responseEntityType); }).collect(Collectors.toList()); ListResponse typedListResponse = new ListResponse<>(responseEntityType); typedListResponse.setItemsPerPage(listResponse.getItemsPerPage()); typedListResponse.setStartIndex(listResponse.getStartIndex()); typedListResponse.setTotalResults(listResponse.getTotalResults()); typedListResponse.setListedResources(typedResources); return (R)typedListResponse; } } /** * used to build a filter expression */ public class FilterBuilder { /** * the original builder to which this builder will return if building the filter is finished */ private final ListBuilder listBuilder; /** * this builder will represent the built filter expression */ private final StringBuilder filterString = new StringBuilder(); /** * tells us how many parenthesis' have been opened so far */ private int openedParenthesis = 0; /** * tells us how many parenthesis' have been closed so far */ private int closedParenthesis = 0; public FilterBuilder(ListBuilder listBuilder, String attributeName, Comparator comparator, String value, boolean openParenthesis) { this.listBuilder = listBuilder; this.openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); } /** * opens a parenthesis for the current filter expression */ private FilterBuilder openParenthesis(boolean openParenthesis) { if (openParenthesis) { openedParenthesis++; filterString.append("("); } return this; } /** * closes a parenthesis for the current filter expression */ public FilterBuilder closeParenthesis() { closedParenthesis++; filterString.append(")"); return this; } /** * closes a parenthesis for the current filter expression */ private FilterBuilder closeParenthesis(boolean closeParenthesis) { if (closeParenthesis) { return closeParenthesis(); } return this; } public FilterBuilder and(String attributeName, Comparator comparator, String value) { return and(false, attributeName, comparator, value); } public FilterBuilder or(String attributeName, Comparator comparator, String value) { return or(false, attributeName, comparator, value); } public FilterBuilder and(String attributeName, Comparator comparator, Boolean value) { return and(false, attributeName, comparator, value); } public FilterBuilder or(String attributeName, Comparator comparator, Boolean value) { return or(false, attributeName, comparator, value); } public FilterBuilder and(String attributeName, Comparator comparator, Integer value) { return and(false, attributeName, comparator, value); } public FilterBuilder or(String attributeName, Comparator comparator, Integer value) { return or(false, attributeName, comparator, value); } public FilterBuilder and(String attributeName, Comparator comparator, Long value) { return and(false, attributeName, comparator, value); } public FilterBuilder or(String attributeName, Comparator comparator, Long value) { return or(false, attributeName, comparator, value); } public FilterBuilder and(String attributeName, Comparator comparator, Double value) { return and(false, attributeName, comparator, value); } public FilterBuilder or(String attributeName, Comparator comparator, Double value) { return or(false, attributeName, comparator, value); } public FilterBuilder and(String attributeName, Comparator comparator, Instant value) { return and(false, attributeName, comparator, value); } public FilterBuilder or(String attributeName, Comparator comparator, Instant value) { return or(false, attributeName, comparator, value); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, String value) { return and(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, String value) { return or(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Boolean value) { return and(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Boolean value) { return or(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Integer value) { return and(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Integer value) { return or(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Long value) { return and(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Long value) { return or(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Double value) { return and(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Double value) { return or(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Instant value) { return and(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Instant value) { return or(openParenthesis, attributeName, comparator, value, false); } public FilterBuilder and(String attributeName, Comparator comparator, String value, boolean closeParenthesis) { return and(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder or(String attributeName, Comparator comparator, String value, boolean closeParenthesis) { return or(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder and(String attributeName, Comparator comparator, Boolean value, boolean closeParenthesis) { return and(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder or(String attributeName, Comparator comparator, Boolean value, boolean closeParenthesis) { return or(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder and(String attributeName, Comparator comparator, Integer value, boolean closeParenthesis) { return and(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder or(String attributeName, Comparator comparator, Integer value, boolean closeParenthesis) { return or(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder and(String attributeName, Comparator comparator, Long value, boolean closeParenthesis) { return and(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder or(String attributeName, Comparator comparator, Long value, boolean closeParenthesis) { return or(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder and(String attributeName, Comparator comparator, Double value, boolean closeParenthesis) { return and(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder or(String attributeName, Comparator comparator, Double value, boolean closeParenthesis) { return or(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder and(String attributeName, Comparator comparator, Instant value, boolean closeParenthesis) { return and(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder or(String attributeName, Comparator comparator, Instant value, boolean closeParenthesis) { return or(false, attributeName, comparator, value, closeParenthesis); } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, String value, boolean closeParenthesis) { filterString.append(" and "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, String value, boolean closeParenthesis) { filterString.append(" or "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Boolean value, boolean closeParenthesis) { filterString.append(" and "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Boolean value, boolean closeParenthesis) { filterString.append(" or "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Integer value, boolean closeParenthesis) { filterString.append(" and "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Integer value, boolean closeParenthesis) { filterString.append(" or "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Long value, boolean closeParenthesis) { filterString.append(" and "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Long value, boolean closeParenthesis) { filterString.append(" or "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Double value, boolean closeParenthesis) { filterString.append(" and "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Double value, boolean closeParenthesis) { filterString.append(" or "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value); closeParenthesis(closeParenthesis); return this; } public FilterBuilder and(boolean openParenthesis, String attributeName, Comparator comparator, Instant value, boolean closeParenthesis) { filterString.append(" and "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value.toString()); closeParenthesis(closeParenthesis); return this; } public FilterBuilder or(boolean openParenthesis, String attributeName, Comparator comparator, Instant value, boolean closeParenthesis) { filterString.append(" or "); openParenthesis(openParenthesis); setExpression(attributeName, comparator, value.toString()); closeParenthesis(closeParenthesis); return this; } /** * adds an expression into the filter * * @param attributeName the attribute name of the expression * @param comparator the comparator to use * @param value the value of the expression */ private void setExpression(String attributeName, Comparator comparator, Object value) { ScimClientConfig scimClientConfig = scimHttpClient.getScimClientConfig(); String comparatorString = scimClientConfig.isUseLowerCaseInFilterComparators() ? comparator.name().toLowerCase() : comparator.name(); filterString.append(attributeName).append(" ").append(comparatorString); if (value instanceof String) { filterString.append(value == null ? "" : " ").append("\"").append(value == null ? "" : value).append("\""); } else { filterString.append(value == null ? "" : " " + value); } } /** * builds the filter string and puts it into the parameter map of the list builder instance */ public ListBuilder build() { if (openedParenthesis != closedParenthesis) { throw new IllegalStateException("error within filter expression\n\topened parentheses: " + openedParenthesis + "\n\tclosed parentheses: " + closedParenthesis + "\n\tfilter: " + filterString); } listBuilder.requestParameters.put(AttributeNames.RFC7643.FILTER, filterString.toString()); return listBuilder; } } /** * the parameters that will be used for the list request */ @java.lang.SuppressWarnings("all") protected Map getRequestParameters() { return this.requestParameters; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy