Package com.opensymphony.xwork2.ognl.accessor

Source Code of com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor

/*
* Copyright 2002-2006,2009 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.opensymphony.xwork2.ognl.accessor;

import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;

import ognl.MethodFailedException;
import ognl.ObjectMethodAccessor;
import ognl.OgnlContext;
import ognl.OgnlRuntime;
import ognl.PropertyAccessor;

import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;


/**
* Allows methods to be executed under normal cirumstances, except when {@link ReflectionContextState#DENY_METHOD_EXECUTION}
* is in the action context with a value of true.
*
* @author Patrick Lightbody
* @author tmjee
*/
public class XWorkMethodAccessor extends ObjectMethodAccessor {
 
  private static final Logger LOG = LoggerFactory.getLogger(XWorkMethodAccessor.class);

    /**
     * @deprecated Use {@link ReflectionContextState#DENY_METHOD_EXECUTION} instead
     */
    @Deprecated public static final String DENY_METHOD_EXECUTION = ReflectionContextState.DENY_METHOD_EXECUTION;
    /**
     * @deprecated Use {@link ReflectionContextState#DENY_INDEXED_ACCESS_EXECUTION} instead
     */
    @Deprecated public static final String DENY_INDEXED_ACCESS_EXECUTION = ReflectionContextState.DENY_INDEXED_ACCESS_EXECUTION;


    @Override
    public Object callMethod(Map context, Object object, String string, Object[] objects) throws MethodFailedException {

        //Collection property accessing
        //this if statement ensures that ognl
        //statements of the form someBean.mySet('keyPropVal')
        //return the set element with value of the keyProp given
       
        if (objects.length==1
                && context instanceof OgnlContext) {
            try {
              OgnlContext ogContext=(OgnlContext)context;
              if (OgnlRuntime.hasSetProperty(ogContext, object, string))  {
                    PropertyDescriptor descriptor=OgnlRuntime.getPropertyDescriptor(object.getClass(), string);
                    Class propertyType=descriptor.getPropertyType();
                    if ((Collection.class).isAssignableFrom(propertyType)) {
                        //go directly through OgnlRuntime here
                        //so that property strings are not cleared
                        //i.e. OgnlUtil should be used initially, OgnlRuntime
                        //thereafter
                       
                        Object propVal=OgnlRuntime.getProperty(ogContext, object, string);
                        //use the Collection property accessor instead of the individual property accessor, because
                        //in the case of Lists otherwise the index property could be used
                        PropertyAccessor accessor=OgnlRuntime.getPropertyAccessor(Collection.class);
                        ReflectionContextState.setGettingByKeyProperty(ogContext,true);
                        return accessor.getProperty(ogContext,propVal,objects[0]);
                    }
              }
            }  catch (Exception oe) {
                //this exception should theoretically never happen
                //log it
              LOG.error("An unexpected exception occurred", oe);
            }

        }

        //HACK - we pass indexed method access i.e. setXXX(A,B) pattern
        if (
                (objects.length == 2 && string.startsWith("set"))
                        ||
                        (objects.length == 1 && string.startsWith("get"))
                ) {
            Boolean exec = (Boolean) context.get(ReflectionContextState.DENY_INDEXED_ACCESS_EXECUTION);
            boolean e = ((exec == null) ? false : exec.booleanValue());
            if (!e) {
                return callMethodWithDebugInfo(context, object, string, objects);
            }
        }
        Boolean exec = (Boolean) context.get(ReflectionContextState.DENY_METHOD_EXECUTION);
        boolean e = ((exec == null) ? false : exec.booleanValue());

        if (!e) {
            return callMethodWithDebugInfo(context, object, string, objects);
        } else {
            return null;
        }
    }

  private Object callMethodWithDebugInfo(Map context, Object object, String methodName,
      Object[] objects) throws MethodFailedException {
    try {
      return super.callMethod(context, object, methodName, objects);
    }
    catch(MethodFailedException e) {
      if (LOG.isDebugEnabled()) {
        if (!(e.getReason() instanceof NoSuchMethodException)) {
          // the method exists on the target object, but something went wrong
          String s = "Error calling method through OGNL: object: [#0] method: [#1] args: [#2]";
          LOG.debug(s, e.getReason(), object.toString(), methodName, Arrays.toString(objects));
        }
      }
      throw e;
    }
  }

    @Override
    public Object callStaticMethod(Map context, Class aClass, String string, Object[] objects) throws MethodFailedException {
        Boolean exec = (Boolean) context.get(ReflectionContextState.DENY_METHOD_EXECUTION);
        boolean e = ((exec == null) ? false : exec.booleanValue());

        if (!e) {
            return callStaticMethodWithDebugInfo(context, aClass, string, objects);
        } else {
            return null;
        }
    }

  private Object callStaticMethodWithDebugInfo(Map context, Class aClass, String methodName,
      Object[] objects) throws MethodFailedException {
    try {
      return super.callStaticMethod(context, aClass, methodName, objects);
    }
    catch(MethodFailedException e) {
      if (LOG.isDebugEnabled()) {
        if (!(e.getReason() instanceof NoSuchMethodException)) {
          // the method exists on the target class, but something went wrong
          String s = "Error calling method through OGNL, class: [#0] method: [#1] args: [#2]";
          LOG.debug(s, e.getReason(), aClass.getName(), methodName, Arrays.toString(objects));
        }
      }
      throw e;
    }
  }
}
TOP

Related Classes of com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.