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

de.captaingoldfish.scim.sdk.server.endpoints.bulkget.BulkGetResolver Maven / Gradle / Ivy

// Generated by delombok at Thu Nov 02 20:38:53 CET 2023
package de.captaingoldfish.scim.sdk.server.endpoints.bulkget;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import de.captaingoldfish.scim.sdk.common.response.BulkResponseGetOperation;
import de.captaingoldfish.scim.sdk.common.response.ScimResponse;
import de.captaingoldfish.scim.sdk.server.schemas.ResourceType;
import de.captaingoldfish.scim.sdk.server.schemas.ResourceTypeFactory;


/**
 * The bulk-get resolver will do get-requests on transitive resources if the requested resource has any
 * transitive references to other resources
 *
 * @author Pascal Knueppel
 * @since 29.08.2022
 */
public class BulkGetResolver
{

  /**
   * the maximum number of recursions that are allowed to retrieve the children. The minimum value is 1 the
   * maximum value depends on the service providers' configuration.
   */
  private final int maxResourceLevel;

  /**
   * this operation contains the parent whose children shall be extracted
   */
  private final ScimResponse parentResourceResponse;

  /**
   * the resources definition
   */
  private final ResourceType resourceType;

  /**
   * the factory is necessary to get the resource definitions of the transitive types to be able to analyze them
   * correctly
   */
  private final ResourceTypeFactory resourceTypeFactory;

  private final BiFunction callResourceEndpoint;

  public BulkGetResolver(int maxResourceLevel,
                         ScimResponse parentResourceResponse,
                         ResourceType resourceType,
                         ResourceTypeFactory resourceTypeFactory,
                         BiFunction callResourceEndpoint)
  {
    this.maxResourceLevel = Math.max(1, maxResourceLevel);
    this.parentResourceResponse = parentResourceResponse;
    this.resourceType = resourceType;
    this.resourceTypeFactory = resourceTypeFactory;
    this.callResourceEndpoint = callResourceEndpoint;
  }

  /**
   * retrieves the referenced resources of the given {@link #parentResourceResponse} e.g. a manager of the
   * enterprise user or the members of a group
   *
   * @return all transitive resources until the given {@link #maxResourceLevel} is reached
   */
  public List getTransitiveResources()
  {
    return getChildrenOfResource(parentResourceResponse, resourceType, 0);
  }

  /**
   * retrieves the children of the given resource
   *
   * @param scimResponse the resource from which the children should be retrieved
   * @param resourceType the resource type definition of the given resource (scimResponse)
   * @param currentDepth the current depth level to prevent the resources from being retrieved from a level that
   *          is too deep (e.g. infinite loop with resources that reference each other)
   * @return the children of the given resource if any
   */
  private List getChildrenOfResource(ScimResponse scimResponse,
                                                               ResourceType resourceType,
                                                               int currentDepth)
  {
    if (currentDepth == maxResourceLevel)
    {
      return Collections.emptyList();
    }
    ResourceReferenceExtractor resourceReferenceExtractor = new ResourceReferenceExtractor(scimResponse, resourceType,
                                                                                           resourceTypeFactory);
    List resourceReferences = resourceReferenceExtractor.getResourceReferences();
    return resourceReferences.stream().map((ResourceReference resourceReference) -> {
      return getChildResource(resourceReference, currentDepth);
    }).collect(Collectors.toList());
  }

  /**
   * retrieves a single child resource
   *
   * @param resourceReference the reference to a child resource
   * @param currentDepth the current depth level to prevent the resources from being retrieved from a level that
   *          is too deep (e.g. infinite loop with resources that reference each other)
   * @return the retrieved child resource
   */
  private BulkResponseGetOperation getChildResource(ResourceReference resourceReference, int currentDepth)
  {
    final String resourceId = resourceReference.getResourceId();
    final ResourceType childResourceType = resourceReference.getResourceType();
    final String nodePath = resourceReference.getNodePath();
    ScimResponse scimResponse = callResourceEndpoint.apply(resourceId, childResourceType);
    List children = new ArrayList<>();
    if (currentDepth < maxResourceLevel)
    {
      children = getChildrenOfResource(scimResponse, childResourceType, currentDepth + 1);
    }
    return BulkResponseGetOperation.builder()
                                   .resource(scimResponse)
                                   .resourceId(resourceId)
                                   .status(scimResponse.getHttpStatus())
                                   .resourceType(childResourceType.getName())
                                   .nodePath(nodePath)
                                   .children(children)
                                   .build();
  }


  @java.lang.SuppressWarnings("all")
  public static class BulkGetResolverBuilder
  {

    @java.lang.SuppressWarnings("all")
    private int maxResourceLevel;

    @java.lang.SuppressWarnings("all")
    private ScimResponse parentResourceResponse;

    @java.lang.SuppressWarnings("all")
    private ResourceType resourceType;

    @java.lang.SuppressWarnings("all")
    private ResourceTypeFactory resourceTypeFactory;

    @java.lang.SuppressWarnings("all")
    private BiFunction callResourceEndpoint;

    @java.lang.SuppressWarnings("all")
    BulkGetResolverBuilder()
    {}

    /**
     * @return {@code this}.
     */
    @java.lang.SuppressWarnings("all")
    public BulkGetResolver.BulkGetResolverBuilder maxResourceLevel(final int maxResourceLevel)
    {
      this.maxResourceLevel = maxResourceLevel;
      return this;
    }

    /**
     * @return {@code this}.
     */
    @java.lang.SuppressWarnings("all")
    public BulkGetResolver.BulkGetResolverBuilder parentResourceResponse(final ScimResponse parentResourceResponse)
    {
      this.parentResourceResponse = parentResourceResponse;
      return this;
    }

    /**
     * @return {@code this}.
     */
    @java.lang.SuppressWarnings("all")
    public BulkGetResolver.BulkGetResolverBuilder resourceType(final ResourceType resourceType)
    {
      this.resourceType = resourceType;
      return this;
    }

    /**
     * @return {@code this}.
     */
    @java.lang.SuppressWarnings("all")
    public BulkGetResolver.BulkGetResolverBuilder resourceTypeFactory(final ResourceTypeFactory resourceTypeFactory)
    {
      this.resourceTypeFactory = resourceTypeFactory;
      return this;
    }

    /**
     * @return {@code this}.
     */
    @java.lang.SuppressWarnings("all")
    public BulkGetResolver.BulkGetResolverBuilder callResourceEndpoint(final BiFunction callResourceEndpoint)
    {
      this.callResourceEndpoint = callResourceEndpoint;
      return this;
    }

    @java.lang.SuppressWarnings("all")
    public BulkGetResolver build()
    {
      return new BulkGetResolver(this.maxResourceLevel, this.parentResourceResponse, this.resourceType,
                                 this.resourceTypeFactory, this.callResourceEndpoint);
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString()
    {
      return "BulkGetResolver.BulkGetResolverBuilder(maxResourceLevel=" + this.maxResourceLevel
             + ", parentResourceResponse=" + this.parentResourceResponse + ", resourceType=" + this.resourceType
             + ", resourceTypeFactory=" + this.resourceTypeFactory + ", callResourceEndpoint="
             + this.callResourceEndpoint + ")";
    }
  }

  @java.lang.SuppressWarnings("all")
  public static BulkGetResolver.BulkGetResolverBuilder builder()
  {
    return new BulkGetResolver.BulkGetResolverBuilder();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy