/*
     We are synchrozing for the case were allowDuplicate is set to false.
     For this case we need to synchronize to avoid a race condition that will
     allow duplicates.
 */
 private synchronized void addRequestFilter(
     AWDefaultRequestFilter newFilter, boolean allowDuplicates) {
   if (allowDuplicates) {
     _defaultRequestFilter.add(newFilter);
   } else {
     boolean found = false;
     int size = _defaultRequestFilter.size();
     for (int i = 0; i < size; i++) {
       AWDefaultRequestFilter existingFilter =
           (AWDefaultRequestFilter) _defaultRequestFilter.get(i);
       if (newFilter.sameAs(existingFilter)) {
         found = true;
       }
     }
     if (!found) {
       _defaultRequestFilter.add(newFilter);
     }
   }
 }
  public AWResponseGenerating processAction(AWRequest request, AWRequestContext requestContext) {
    AWApplication application = application();
    AWResponseGenerating response = null;

    String[] directActionName = parseDirectActionRequest(request);

    // isReloadable() returns true if we have hotswap reloading enabled
    String className = application.directActionClassNameForKey(directActionName[ClassNameIndex]);
    directActionName[ClassNameIndex] = className;

    Class directActionClass = application.resourceManager().classForName(className);

    if (AWUtil.getClassLoader().isReloadable(className)) {
      Class reloadedClass = AWUtil.getClassLoader().checkReloadClass(directActionClass);
      if (reloadedClass != directActionClass) {
        application.resourceManager().removeClass(className);
        directActionClass = reloadedClass;
      }
    }
    String actionName = directActionName[ActionNameIndex];
    requestContext.setCurrentDirectAction(className, actionName);
    AWDirectAction directAction = null;
    try {
      directAction = (AWDirectAction) directActionClass.newInstance();
    } catch (IllegalAccessException illegalAccessException) {
      throw new AWGenericException(illegalAccessException);
    } catch (InstantiationException instantiationException) {
      throw new AWGenericException(
          "*** Error: cannot instantiate direct action class named \""
              + directActionName[ClassNameIndex]
              + "\"",
          instantiationException);
    }

    directAction.init(requestContext);

    try {
      if (request.formValueForKey(AWRequestContext.RefreshRequestKey) != null) {
        // if this is a refresh request (ie. forward track over a redirect from
        // another app, then see if we have a valid session and we have a
        // page to refresh.  Otherwise, this app must have been restarted but
        // the other app was not so there is a mismatch in state.  In this case,
        // actually execute the direct action.
        AWSession session = requestContext.session(false);
        if (session != null) {
          AWPage page = session.restoreCurrentPage();
          if (page != null) {
            if (page.pageComponent().isBoundary()) {
              // need to forward track here and then redirect to
              // refresh the page ...
              requestContext.setHistoryAction(AWSession.ForwardTrackRequest);
              session.initRequestType();
              page = session.restoreNextPage(page);
            }
            AWRedirect redirectComponent =
                (AWRedirect) application.createPageWithName(AWRedirect.PageName, requestContext);
            String effectiveUrl =
                AWComponentActionRequestHandler.SharedInstance.refreshUrl(requestContext);

            redirectComponent.setUrl(effectiveUrl);
            redirectComponent.setSelfRedirect(true);
            requestContext.setPage(redirectComponent.page());
            response = requestContext.generateResponse();
          }
        }
      }

      if (response == null) {
        AWResponseGenerating actionResults = null;

        if (!request.hasHandler()) {
          // If there is not handler specified, then the user is
          // accessing the /Main page and that is the only time
          // that we want to execute the filters.
          for (int i = 0; i < _defaultRequestFilter.size(); i++) {
            AWDefaultRequestFilter filter = (AWDefaultRequestFilter) _defaultRequestFilter.get(i);
            filter.execute(requestContext);
          }
        }
        if (!directAction.skipValidation(actionName)) {
          if (directAction.shouldValidateTopFrame(actionName)) {
            response = directAction.validateTopFramePost(requestContext);
            if (response != null) {
              return response;
            }
          }

          if (!AWDirectAction.isServerManagementAction(request)
              && directAction.shouldValidateNode(actionName)) {
            directAction.validateNode(requestContext, directActionName[ClassNameIndex], actionName);
          }

          if (directAction.shouldValidateSession(actionName)) {
            directAction.validateSession(requestContext);
          }

          if (directAction.shouldValidateRequest(actionName)) {
            directAction.validateRequest(requestContext);
          }
        }

        actionResults = directAction.performActionNamed(directActionName[ActionNameIndex]);

        Assert.that(actionResults != null, "Direct action result cannot be null.");

        // Allow response to replace itself (see AWRedirect for example)
        if (actionResults instanceof AWResponseGenerating.ResponseSubstitution) {
          actionResults =
              ((AWResponseGenerating.ResponseSubstitution) actionResults).replacementResponse();
        }

        return actionResults;
      }
    } catch (AWNodeChangeException e) {
      AWNodeValidator nv = e.getNodeValidator();
      AWResponseGenerating handlerResults = nv.handleNodeValidationException(requestContext);
      nv.terminateCurrentSession(requestContext);
      response = handlerResults.generateResponse();
    } catch (AWSessionValidationException exception) {
      try {
        if (AWConcreteApplication.IsDebuggingEnabled) {
          Log.aribaweb.debug(
              "AWDirectActionRequestHandler: handling session " + "validation exception");
        }

        // if there is a default validator, run it here
        AWNodeValidator nv = AWNodeManager.getDefaultNodeValidator();
        if (nv != null && !nv.isValid(requestContext)) {
          Log.aribaweb_nodeValidate.debug(
              "AWDirectActionRequestHandler: invalid node. "
                  + "NodeValidator generating response.");
          AWResponseGenerating handlerResults = nv.handleNodeValidationException(requestContext);
          nv.terminateCurrentSession(requestContext);
          response = handlerResults.generateResponse();
        } else {
          AWResponseGenerating handlerResults =
              handleSessionValidationError(requestContext, exception);
          // If there is not valid HttpSession, create a new one to enable
          // load balancers which use the sessionid.
          if (requestContext.httpSession(false) == null) {
            // request.getSession(true);
            requestContext.createHttpSession();
            Log.aribaweb_session.debug("AWDirectActionRequestHandler: create HttpSession");
          }
          if (exception instanceof AWClearBrowserHistoryException) {
            AWComponent actionResultsComponent = (AWComponent) handlerResults;
            response = clearBrowserHistory(requestContext, actionResultsComponent);
          } else if (requestContext.session(false) != null
              && handlerResults instanceof AWComponent) {
            AWComponent actionResultsComponent = (AWComponent) handlerResults;
            AWPage actionResultsPage = actionResultsComponent.page();
            attemptSavePage(requestContext, actionResultsPage);
          }
          if (response == null) {
            response = handlerResults.generateResponse();
          }
        }
      } catch (RuntimeException e) {
        AWGenericException newException =
            new AWGenericException(
                "Error occurred while handling session validation.  Please make"
                    + " sure session validation is configured properly.",
                e);
        return handleException(requestContext, newException).generateResponse();
      }
    } catch (AWSessionRestorationException exception) {
      requestContext.createHttpSession();
      response = handleSessionRestorationError(requestContext).generateResponse();
    } catch (AWSiteUnavailableException e) {
      response = handleSiteUnavailableException(requestContext);
    } catch (AWRemoteHostMismatchException exception) {
      response = handleRemoteHostMismatchException(requestContext, exception);
    } catch (Throwable t) {
      response = handleUncaughtException(requestContext, t);
    }
    return response;
  }