@Override
  public String intercept(ActionInvocation actionInvocation) throws Exception {
    ActionConfig actionConfig = actionInvocation.getProxy().getConfig();

    final Map<String, String> staticParams = actionConfig.getParams();

    if (staticParams != null) {
      // ---------------------------------------------------------------------
      // Push the specified static parameters onto the value stack
      // ---------------------------------------------------------------------

      Map<String, Object> matches = new HashMap<>();

      for (Map.Entry<String, String> entry : staticParams.entrySet()) {
        if (standardParams.contains(entry.getKey())) {
          matches.put(entry.getKey(), entry.getValue());
        } else if (commaSeparatedParams.contains(entry.getKey())) {
          String[] values = entry.getValue().split(",");

          for (int i = 0; i < values.length; i++) {
            values[i] = values[i].trim();
          }

          matches.put(entry.getKey(), values);
        }
      }

      actionInvocation.getStack().push(matches);
    }

    // TODO: move this to its own systemInfoInterceptor?
    Map<String, Object> systemInfo = new HashMap<>();

    String revision = systemService.getSystemInfo().getRevision();

    if (StringUtils.isEmpty(revision)) {
      revision = "__dev__";
    }

    systemInfo.put("buildRevision", revision);
    actionInvocation.getStack().push(systemInfo);

    return actionInvocation.invoke();
  }
  public Collection<String> getRequiredAuthorities(ActionConfig actionConfig) {
    final Map<String, String> staticParams = actionConfig.getParams();

    if (staticParams == null || !staticParams.containsKey(requiredAuthoritiesKey)) {
      return Collections.emptySet();
    }

    final String param = staticParams.get(requiredAuthoritiesKey);

    HashSet<String> requiredAuthorities = new HashSet<String>();

    StringTokenizer t = new StringTokenizer(param, "\t\n\r ,");

    while (t.hasMoreTokens()) {
      requiredAuthorities.add(t.nextToken());
    }

    return requiredAuthorities;
  }
  public void testGlobalResultInheritenceTest() throws Exception {
    ConfigurationProvider provider =
        buildConfigurationProvider(
            "com/opensymphony/xwork2/config/providers/xwork-test-global-result-inheritence.xml");

    ConfigurationManager configurationManager = new ConfigurationManager();
    configurationManager.addContainerProvider(new XWorkConfigurationProvider());
    configurationManager.addContainerProvider(provider);
    Configuration configuration = configurationManager.getConfiguration();

    ActionConfig parentActionConfig =
        configuration.getRuntimeConfiguration().getActionConfig("/base", "parentAction");
    ActionConfig anotherActionConfig =
        configuration.getRuntimeConfiguration().getActionConfig("/base", "anotherAction");
    ActionConfig childActionConfig =
        configuration.getRuntimeConfiguration().getActionConfig("/base", "childAction");

    ResultConfig parentResultConfig1 = parentActionConfig.getResults().get("mockResult1");
    ResultConfig parentResultConfig2 = parentActionConfig.getResults().get("mockResult2");
    ResultConfig anotherResultConfig1 = anotherActionConfig.getResults().get("mockResult1");
    ResultConfig anotherResultConfig2 = anotherActionConfig.getResults().get("mockResult2");
    ResultConfig childResultConfig1 = childActionConfig.getResults().get("mockResult1");
    ResultConfig childResultConfig2 = childActionConfig.getResults().get("mockResult2");

    System.out.println(parentResultConfig1.getParams().get("identity"));
    System.out.println(parentResultConfig2.getParams().get("identity"));
    System.out.println(anotherResultConfig1.getParams().get("identity"));
    System.out.println(anotherResultConfig2.getParams().get("identity"));
    System.out.println(childResultConfig1.getParams().get("identity"));
    System.out.println(childResultConfig2.getParams().get("identity"));

    assertFalse(parentResultConfig1 == anotherResultConfig1);
    assertFalse(parentResultConfig2 == anotherResultConfig2);

    assertFalse(parentResultConfig1 == childResultConfig1);
    assertTrue(parentResultConfig2 == childResultConfig2);
  }
  /**
   * Tests creating action flow override configuration.
   *
   * @throws Exception when something goes wrong.
   */
  @Test
  public void testCorrectFlowOverride() throws Exception {
    ActionProxy proxy = getActionProxy("/correctFlowOverride/correctFlowOverride");
    Assert.assertNotNull(proxy);
    proxy.getInvocation().getInvocationContext().setSession(new HashMap<String, Object>());
    proxy.execute();

    ActionConfig overriddenViewConf =
        configuration
            .getRuntimeConfiguration()
            .getActionConfig("/correctFlowOverride", "savePhone-2ViewOverride");

    Assert.assertNotNull(overriddenViewConf);
    Assert.assertEquals("phone", overriddenViewConf.getMethodName());
    Assert.assertEquals(
        "anotherPhone",
        overriddenViewConf
            .getResults()
            .get(Action.SUCCESS)
            .getParams()
            .get(ServletDispatcherResult.DEFAULT_PARAM));

    ActionConfig actionConfig =
        configuration
            .getRuntimeConfiguration()
            .getActionConfig("/correctFlowOverride", "saveName-1ViewOverride");

    Assert.assertNotNull(actionConfig);
    Assert.assertEquals("executeOverride", actionConfig.getMethodName());
    Assert.assertEquals(
        "name",
        actionConfig
            .getResults()
            .get(Action.SUCCESS)
            .getParams()
            .get(ServletDispatcherResult.DEFAULT_PARAM));
  }
  public void testInterceptorStackParamOveriding() throws Exception {
    DefaultConfiguration conf = new DefaultConfiguration();
    final XmlConfigurationProvider p =
        new XmlConfigurationProvider(
            "com/opensymphony/xwork2/config/providers/xwork-test-interceptor-stack-param-overriding.xml");
    DefaultFileManagerFactory factory = new DefaultFileManagerFactory();
    factory.setContainer(container);
    factory.setFileManager(new DefaultFileManager());
    p.setFileManagerFactory(factory);
    configurationManager.addContainerProvider(p);
    conf.reloadContainer(
        new ArrayList<ContainerProvider>() {
          {
            add(new XWorkConfigurationProvider());
            add(p);
          }
        });

    RuntimeConfiguration rtConf = conf.getRuntimeConfiguration();

    ActionConfig actionOne = rtConf.getActionConfig("", "actionOne");
    ActionConfig actionTwo = rtConf.getActionConfig("", "actionTwo");

    List actionOneInterceptors = actionOne.getInterceptors();
    List actionTwoInterceptors = actionTwo.getInterceptors();

    assertNotNull(actionOne);
    assertNotNull(actionTwo);
    assertNotNull(actionOneInterceptors);
    assertNotNull(actionTwoInterceptors);
    assertEquals(actionOneInterceptors.size(), 3);
    assertEquals(actionTwoInterceptors.size(), 3);

    InterceptorMapping actionOneInterceptorMapping1 =
        (InterceptorMapping) actionOneInterceptors.get(0);
    InterceptorMapping actionOneInterceptorMapping2 =
        (InterceptorMapping) actionOneInterceptors.get(1);
    InterceptorMapping actionOneInterceptorMapping3 =
        (InterceptorMapping) actionOneInterceptors.get(2);
    InterceptorMapping actionTwoInterceptorMapping1 =
        (InterceptorMapping) actionTwoInterceptors.get(0);
    InterceptorMapping actionTwoInterceptorMapping2 =
        (InterceptorMapping) actionTwoInterceptors.get(1);
    InterceptorMapping actionTwoInterceptorMapping3 =
        (InterceptorMapping) actionTwoInterceptors.get(2);

    assertNotNull(actionOneInterceptorMapping1);
    assertNotNull(actionOneInterceptorMapping2);
    assertNotNull(actionOneInterceptorMapping3);
    assertNotNull(actionTwoInterceptorMapping1);
    assertNotNull(actionTwoInterceptorMapping2);
    assertNotNull(actionTwoInterceptorMapping3);

    assertEquals(
        ((InterceptorForTestPurpose) actionOneInterceptorMapping1.getInterceptor()).getParamOne(),
        "i1p1");
    assertEquals(
        ((InterceptorForTestPurpose) actionOneInterceptorMapping1.getInterceptor()).getParamTwo(),
        "i1p2");
    assertEquals(
        ((InterceptorForTestPurpose) actionOneInterceptorMapping2.getInterceptor()).getParamOne(),
        "i2p1");
    assertEquals(
        ((InterceptorForTestPurpose) actionOneInterceptorMapping2.getInterceptor()).getParamTwo(),
        null);
    assertEquals(
        ((InterceptorForTestPurpose) actionOneInterceptorMapping3.getInterceptor()).getParamOne(),
        null);
    assertEquals(
        ((InterceptorForTestPurpose) actionOneInterceptorMapping3.getInterceptor()).getParamTwo(),
        null);

    assertEquals(
        ((InterceptorForTestPurpose) actionTwoInterceptorMapping1.getInterceptor()).getParamOne(),
        null);
    assertEquals(
        ((InterceptorForTestPurpose) actionTwoInterceptorMapping1.getInterceptor()).getParamTwo(),
        null);
    assertEquals(
        ((InterceptorForTestPurpose) actionTwoInterceptorMapping2.getInterceptor()).getParamOne(),
        null);
    assertEquals(
        ((InterceptorForTestPurpose) actionTwoInterceptorMapping2.getInterceptor()).getParamTwo(),
        "i2p2");
    assertEquals(
        ((InterceptorForTestPurpose) actionTwoInterceptorMapping3.getInterceptor()).getParamOne(),
        "i3p1");
    assertEquals(
        ((InterceptorForTestPurpose) actionTwoInterceptorMapping3.getInterceptor()).getParamTwo(),
        "i3p2");
  }
  /**
   * Clones the ActionConfig and its children, replacing various properties with the values of the
   * wildcard-matched strings.
   *
   * @param path The requested path
   * @param orig The original ActionConfig
   * @param vars A Map of wildcard-matched strings
   * @return A cloned ActionConfig with appropriate properties replaced with wildcard-matched values
   */
  @Override
  public ActionConfig convert(String path, ActionConfig orig, Map<String, String> vars) {

    String methodName = convertParam(orig.getMethodName(), vars);

    if (StringUtils.isEmpty(methodName)) {
      methodName = ActionConfig.DEFAULT_METHOD;
    }

    if (!orig.isAllowedMethod(methodName)) {
      return null;
    }

    String className = convertParam(orig.getClassName(), vars);
    String pkgName = convertParam(orig.getPackageName(), vars);

    Map<String, String> params = replaceParameters(orig.getParams(), vars);

    Map<String, ResultConfig> results = new LinkedHashMap<>();
    for (String name : orig.getResults().keySet()) {
      ResultConfig result = orig.getResults().get(name);
      name = convertParam(name, vars);
      ResultConfig r =
          new ResultConfig.Builder(name, convertParam(result.getClassName(), vars))
              .addParams(replaceParameters(result.getParams(), vars))
              .build();
      results.put(name, r);
    }

    List<ExceptionMappingConfig> exs = new ArrayList<ExceptionMappingConfig>();
    for (ExceptionMappingConfig ex : orig.getExceptionMappings()) {
      String name = convertParam(ex.getName(), vars);
      String exClassName = convertParam(ex.getExceptionClassName(), vars);
      String exResult = convertParam(ex.getResult(), vars);
      Map<String, String> exParams = replaceParameters(ex.getParams(), vars);
      ExceptionMappingConfig e =
          new ExceptionMappingConfig.Builder(name, exClassName, exResult)
              .addParams(exParams)
              .build();
      exs.add(e);
    }

    return new ActionConfig.Builder(pkgName, orig.getName(), className)
        .methodName(methodName)
        .addParams(params)
        .addResultConfigs(results)
        .addInterceptors(orig.getInterceptors())
        .addExceptionMappings(exs)
        .location(orig.getLocation())
        .build();
  }
  @Override
  public String intercept(ActionInvocation invocation) throws Exception {

    ActionConfig config = invocation.getProxy().getConfig();
    ActionContext ac = invocation.getInvocationContext();
    Object action = invocation.getAction();

    // get the action's parameters
    final Map<String, String> parameters = config.getParams();

    if (parameters.containsKey(aliasesKey)) {

      String aliasExpression = parameters.get(aliasesKey);
      ValueStack stack = ac.getValueStack();
      Object obj = stack.findValue(aliasExpression);

      if (obj != null && obj instanceof Map) {
        // get secure stack
        ValueStack newStack = valueStackFactory.createValueStack(stack);
        boolean clearableStack = newStack instanceof ClearableValueStack;
        if (clearableStack) {
          // if the stack's context can be cleared, do that to prevent OGNL
          // from having access to objects in the stack, see XW-641
          ((ClearableValueStack) newStack).clearContextValues();
          Map<String, Object> context = newStack.getContext();
          ReflectionContextState.setCreatingNullObjects(context, true);
          ReflectionContextState.setDenyMethodExecution(context, true);
          ReflectionContextState.setReportingConversionErrors(context, true);

          // keep locale from original context
          context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE));
        }

        // override
        Map aliases = (Map) obj;
        for (Object o : aliases.entrySet()) {
          Map.Entry entry = (Map.Entry) o;
          String name = entry.getKey().toString();
          String alias = (String) entry.getValue();
          Object value = stack.findValue(name);
          if (null == value) {
            // workaround
            Map<String, Object> contextParameters = ActionContext.getContext().getParameters();

            if (null != contextParameters) {
              value = contextParameters.get(name);
            }
          }
          if (null != value) {
            try {
              newStack.setValue(alias, value);
            } catch (RuntimeException e) {
              if (devMode) {
                String developerNotification =
                    LocalizedTextUtil.findText(
                        ParametersInterceptor.class,
                        "devmode.notification",
                        ActionContext.getContext().getLocale(),
                        "Developer Notification:\n{0}",
                        new Object[] {
                          "Unexpected Exception caught setting '"
                              + entry.getKey()
                              + "' on '"
                              + action.getClass()
                              + ": "
                              + e.getMessage()
                        });
                LOG.error(developerNotification);
                if (action instanceof ValidationAware) {
                  ((ValidationAware) action).addActionMessage(developerNotification);
                }
              }
            }
          }
        }

        if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null))
          stack
              .getContext()
              .put(
                  ActionContext.CONVERSION_ERRORS,
                  newStack.getContext().get(ActionContext.CONVERSION_ERRORS));
      } else {
        LOG.debug("invalid alias expression:" + aliasesKey);
      }
    }

    return invocation.invoke();
  }