@Override
  public String doIntercept(ActionInvocation invocation) throws Exception {
    Object action = invocation.getAction();
    if (!(action instanceof NoParameters)) {
      ActionContext ac = invocation.getInvocationContext();
      final Map<String, Object> parameters = retrieveParameters(ac);

      if (LOG.isDebugEnabled()) {
        LOG.debug("Setting params " + getParameterLogMap(parameters));
      }

      if (parameters != null) {
        Map<String, Object> contextMap = ac.getContextMap();
        try {
          ReflectionContextState.setCreatingNullObjects(contextMap, true);
          ReflectionContextState.setDenyMethodExecution(contextMap, true);
          ReflectionContextState.setReportingConversionErrors(contextMap, true);

          ValueStack stack = ac.getValueStack();
          setParameters(action, stack, parameters);
        } finally {
          ReflectionContextState.setCreatingNullObjects(contextMap, false);
          ReflectionContextState.setDenyMethodExecution(contextMap, false);
          ReflectionContextState.setReportingConversionErrors(contextMap, false);
        }
      }
    }
    return invocation.invoke();
  }
Ejemplo n.º 2
0
  @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();
  }
  protected void setParameters(
      Object action, ValueStack stack, final Map<String, Object> parameters) {
    ParameterNameAware parameterNameAware =
        (action instanceof ParameterNameAware) ? (ParameterNameAware) action : null;

    Map<String, Object> params;
    Map<String, Object> acceptableParameters;
    if (ordered) {
      params = new TreeMap<String, Object>(getOrderedComparator());
      acceptableParameters = new TreeMap<String, Object>(getOrderedComparator());
      params.putAll(parameters);
    } else {
      params = new TreeMap<String, Object>(parameters);
      acceptableParameters = new TreeMap<String, Object>();
    }

    for (Map.Entry<String, Object> entry : params.entrySet()) {
      String name = entry.getKey();

      boolean acceptableName =
          acceptableName(name)
              && (parameterNameAware == null || parameterNameAware.acceptableParameterName(name));

      if (acceptableName) {
        acceptableParameters.put(name, entry.getValue());
      }
    }

    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));
    }

    boolean memberAccessStack = newStack instanceof MemberAccessValueStack;
    if (memberAccessStack) {
      // block or allow access to properties
      // see WW-2761 for more details
      MemberAccessValueStack accessValueStack = (MemberAccessValueStack) newStack;
      accessValueStack.setAcceptProperties(acceptParams);
      accessValueStack.setExcludeProperties(excludeParams);
    }

    for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {
      String name = entry.getKey();
      Object value = entry.getValue();
      try {
        newStack.setValue(name, 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 '"
                        + name
                        + "' 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));

    addParametersToContext(ActionContext.getContext(), acceptableParameters);
  }