/**
   * Internal factory method used by all the public methods to call into the actual PepRequestImpl
   * constructor.
   *
   * <p>Note to developers: This method makes the actual call to {@link
   * PepRequestImpl#PepRequestImpl(AzRequestContext, PepRequestFactory, PepRequestOperation)}.
   *
   * <p>Note that the above constructor is where the PepApi objects, which are contained in this
   * PepRequestFactoryImpl class are related to the AzApi objects thru the {@link AzRequestContext}
   * handle obtained from the AzApi {@link AzService} implementation.
   *
   * <p>The newPepRequest methods continue on return from obtaining the underlying PDP AzApi
   * AzRequestContext, and are able to invoke the mappers to translate the local objects to the
   * AzApi objects.
   *
   * <p>Note also, that if this PepApi impl is used for guidance for implementing a direct
   * PepApi-PDP interface, that the modules here that bridge to AzApi would likely have
   * corresponding modules to bridge to the specific PDP API.
   *
   * <p>Note also, that the long term goal of PepApi/AzApi is to use AzApi as a common set of PDP
   * request/response objects that any PDP can map from and any PEP can map to, which will provide a
   * common interoperability layer.
   *
   * <p>Note also, that it is also recognized that direct links from PepApi to PDP can provide
   * improved performance, so, in conjunction with proper configuration, it should be possible to
   * provide both full interoperability and high performance. For full flexibility for any request
   * to go to any pdp at any time, it is likely the common interface will be required, however, if
   * there are stable configurations and expected policy processing sequences, then configuration
   * can likely expose sections where direct links can be used with little or no sacrifice of
   * interoperability.
   *
   * @param operation
   * @return a PepRequest with initial AzEntity objects ready to be populated
   */
  protected PepRequest newPEPRequest(PepRequestOperation operation) {

    // Use AzApi AzService to create an AzRequestContext:
    AzService azHandle = AzServiceFactory.getAzService();
    AzRequestContext azReqCtx = azHandle.createAzRequestContext(); // [a07]

    // Create a basic PepRequestImpl that can be further populated
    // on return to the caller
    PepRequest pepRequest = new PepRequestImpl(azReqCtx, this, operation);

    return pepRequest;
  }
  /**
   * Constructor of Pep Request Factory uses the DefaultDecisionHandler
   *
   * @param containerName The name of the PEP. This is used as the issuer of all of the attributes.
   * @param azService A handle to the AzService
   */
  public PepRequestFactoryImpl(String containerName, AzService azService) {
    this();
    this.containerName = containerName;
    this.azService = azService;
    String name = DEFAULT_PROVIDER_NAME;

    if (log.isTraceEnabled())
      log.trace(
          "\n    Registering provider, \n\t"
              + name
              + " = "
              + azService.getClass().getName()
              + ".\n");
    AzServiceFactory.registerProvider(name, azService);
  }
  /**
   * Constructor that allows for the inclusion of custom PreDecisionHandler, DecisionHandler and
   * PostDecsionHandler
   *
   * @param containerName The name of the PEP. This is used as the issuer of all of the attributes.
   * @param azService A handle to the AzService
   * @param preDecideHandlers
   * @param decideHandler
   * @param postDecideHandlers
   */
  public PepRequestFactoryImpl(
      String containerName,
      AzService azService,
      List<PreDecisionHandler> preDecideHandlers,
      DecisionHandler decideHandler,
      List<PostDecisionHandler> postDecideHandlers) {
    this(preDecideHandlers, decideHandler, postDecideHandlers);
    this.containerName = containerName;
    this.azService = azService;
    String name = DEFAULT_PROVIDER_NAME;

    if (log.isTraceEnabled())
      log.trace(
          "\n    Registering provider, \n\t"
              + name
              + " = "
              + azService.getClass().getName()
              + ".\n");

    AzServiceFactory.registerProvider(name, azService);
  }