/** create and submit the portlet content rendering job to the thread pool */
  protected IPortletRenderExecutionWorker startPortletRenderInternal(
      IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) {
    // first check to see if there is a Throwable in the session for this IPortletWindowId
    final Map<IPortletWindowId, Exception> portletFailureMap = getPortletErrorMap(request);
    final Exception cause = portletFailureMap.remove(portletWindowId);

    final IPortletRenderExecutionWorker portletRenderExecutionWorker;
    if (null != cause) {
      // previous action failed, dispatch to errorPortlet immediately
      portletRenderExecutionWorker =
          this.portletWorkerFactory.createFailureWorker(request, response, portletWindowId, cause);
    } else {
      IPortletWindow portletWindow =
          portletWindowRegistry.getPortletWindow(request, portletWindowId);
      IPortletDefinition portletDef = portletWindow.getPortletEntity().getPortletDefinition();
      if (portletDef.getLifecycleState().equals(PortletLifecycleState.MAINTENANCE)) {
        // Prevent the portlet from rendering;  replace with a helpful "Out of Service" message
        portletRenderExecutionWorker =
            this.portletWorkerFactory.createFailureWorker(
                request, response, portletWindowId, new MaintenanceModeException());
      } else {
        // Happy path
        portletRenderExecutionWorker =
            this.portletWorkerFactory.createRenderWorker(request, response, portletWindowId);
      }
    }

    portletRenderExecutionWorker.submit();

    final Map<IPortletWindowId, IPortletRenderExecutionWorker> portletRenderingMap =
        this.getPortletRenderingMap(request);
    portletRenderingMap.put(portletWindowId, portletRenderExecutionWorker);

    return portletRenderExecutionWorker;
  }
 protected IPortletDefinition getPortletDefinition(
     IPortletWindowId portletWindowId, HttpServletRequest request) {
   final IPortletWindow portletWindow =
       this.portletWindowRegistry.getPortletWindow(request, portletWindowId);
   final IPortletEntity parentPortletEntity = portletWindow.getPortletEntity();
   return parentPortletEntity.getPortletDefinition();
 }
 /**
  * @param portletWindowId
  * @param request
  * @return
  */
 protected boolean doesPortletNeedHeaderWorker(
     IPortletWindowId portletWindowId, HttpServletRequest request) {
   IPortletWindow portletWindow =
       this.portletWindowRegistry.getPortletWindow(request, portletWindowId);
   PortletDefinition portletDefinition =
       portletWindow.getPlutoPortletWindow().getPortletDefinition();
   ContainerRuntimeOption renderHeaderOption =
       portletDefinition.getContainerRuntimeOption(PORTLET_RENDER_HEADERS_OPTION);
   boolean result = false;
   if (renderHeaderOption != null) {
     result = renderHeaderOption.getValues().contains(Boolean.TRUE.toString());
   }
   logger.debug(
       "Portlet {} need render header worker: {}", portletDefinition.getPortletName(), result);
   return result;
 }
  @Override
  public void postExecution(
      HttpServletRequest request,
      HttpServletResponse response,
      IPortletExecutionContext context,
      Exception e) {
    final IPortletWindowId portletWindowId = context.getPortletWindowId();
    final IPortletWindow portletWindow =
        this.portletWindowRegistry.getPortletWindow(request, portletWindowId);
    final IPortletEntity portletEntity = portletWindow.getPortletEntity();
    final IPortletDefinition portletDefinition = portletEntity.getPortletDefinition();
    final IPortletDescriptorKey portletDescriptorKey = portletDefinition.getPortletDescriptorKey();

    final AtomicInteger counter = this.executionCount.get(portletDescriptorKey);
    counter.incrementAndGet();
  }
  /* (non-Javadoc)
   * @see org.apereo.portal.portlet.rendering.IPortletExecutionManager#doPortletAction(org.apereo.portal.portlet.om.IPortletWindowId, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  @Override
  public void doPortletAction(
      IPortletWindowId portletWindowId, HttpServletRequest request, HttpServletResponse response) {
    final long timeout = getPortletActionTimeout(portletWindowId, request);

    final IPortletExecutionWorker<Long> portletActionExecutionWorker =
        this.portletWorkerFactory.createActionWorker(request, response, portletWindowId);
    portletActionExecutionWorker.submit();

    try {
      portletActionExecutionWorker.get(timeout);
    } catch (Exception e) {
      // put the exception into the error map for the session
      final Map<IPortletWindowId, Exception> portletFailureMap = getPortletErrorMap(request);
      portletFailureMap.put(portletWindowId, e);
    }

    // If the worker is still running add it to the hung-workers queue
    if (!portletActionExecutionWorker.isComplete()) {
      cancelWorker(request, portletActionExecutionWorker);
    }

    // Is this portlet permitted to emit events?  (Or is it disablePortletEvents=true?)
    final IPortletWindow portletWindow =
        portletWindowRegistry.getPortletWindow(request, portletWindowId);
    IPortletDefinition portletDefinition = portletWindow.getPortletEntity().getPortletDefinition();
    IPortletDefinitionParameter disablePortletEvents =
        portletDefinition.getParameter(DISABLE_PORTLET_EVENTS_PARAMETER);
    if (disablePortletEvents != null && Boolean.parseBoolean(disablePortletEvents.getValue())) {
      logger.info(
          "Ignoring portlet events for portlet '{}' because they have been disabled.",
          portletDefinition.getFName());
    } else {
      // Proceed with events...
      final PortletEventQueue portletEventQueue =
          this.eventCoordinationService.getPortletEventQueue(request);
      this.doPortletEvents(portletEventQueue, request, response);
    }
  }