Commits

plightbo  committed 0236b0b
  • Participants
  • Parent commits ea2f45e

Comments (0)

Files changed (10)

File src/java/com/opensymphony/xwork/ActionInvocation.java

  * An ActionInvocation represents the execution state of an Action. It holds the Interceptors and the Action instance.
  * By repeated re-entrant execution of the invoke() method, initially by the ActionProxy, then by the Interceptors, the
  * Interceptors are all executed, and then the Action and the Result.
+ *
  * @author Jason Carreira
- * Created Jun 9, 2003 11:37:27 AM
  * @see com.opensymphony.xwork.ActionProxy
  */
 public interface ActionInvocation extends Serializable {
 
     /**
     * Get the Action associated with this ActionInvocation
-    * @return
     */
     Action getAction();
 
     * Gets the ActionContext associated with this ActionInvocation. The ActionProxy is
     * responsible for setting this ActionContext onto the ThreadLocal before invoking
     * the ActionInvocation and resetting the old ActionContext afterwards.
-    * @return
     */
     ActionContext getInvocationContext();
 
     /**
      * Get the ActionProxy holding this ActionInvocation
-     * @return
      */
     ActionProxy getProxy();
 
     * DefaultActionInvocation's result has not been executed before, the Result instance will be created and populated with
     * the result params.
     * @return a Result instance
-    * @throws java.lang.Exception
     */
     Result getResult() throws Exception;
 
     /**
     * Gets the result code returned from this ActionInvocation
-    * @return
     */
     String getResultCode();
 
     * Register a com.opensymphony.xwork.interceptor.PreResultListener to be notified after the Action is executed and
     * before the Result is executed. The ActionInvocation implementation must guarantee that listeners will be called in
     * the order in which they are registered. Listener registration and execution does not need to be thread-safe.
-    * @param listener
     */
     void addPreResultListener(PreResultListener listener);
 
     * one. If Interceptors choose not to short-circuit ActionInvocation processing and return their own return code,
     * they will call invoke() to allow the next Interceptor to execute. If there are no more Interceptors to be applied,
     * the Action is executed. If the ActionProxy getExecuteResult() method returns true, the Result is also executed.
-    * @return
-    * @throws Exception
     */
     String invoke() throws Exception;
 }

File src/java/com/opensymphony/xwork/ObjectFactory.java

 import com.opensymphony.xwork.config.entities.ActionConfig;
 import com.opensymphony.xwork.config.entities.InterceptorConfig;
 import com.opensymphony.xwork.config.entities.ResultConfig;
-import com.opensymphony.xwork.config.providers.InterceptorBuilder;
 import com.opensymphony.xwork.interceptor.Interceptor;
 import com.opensymphony.xwork.util.OgnlUtil;
 import com.opensymphony.xwork.validator.Validator;
  * ObjectFactory is responsible for building the core framework objects. Users may register their own implementation of
  * the ObjectFactory to control instantiation of these Objects.
  *
+ * This default implemented uses the {@link #buildBean(java.lang.Class) buildBean} method to create all classes
+ * (interceptors, actions, results, etc). 
+ *
  * @author Jason Carreira
- * Date: Feb 26, 2004 9:02:57 PM
  */
 public class ObjectFactory {
     //~ Static fields/initializers /////////////////////////////////////////////
 
     /**
      * Build an Action of the given type
-     * @param config
      */
     public Action buildAction(ActionConfig config) throws Exception {
-        return (Action) config.getClazz().newInstance();
+        return (Action) buildBean(config.getClazz());
     }
 
     /**
      * Build a generic Java object of the given type.
+     *
      * @param clazz the type of Object to build
      */
     public Object buildBean(Class clazz) throws Exception {
      * the Interceptor config and the interceptor ref Map (the interceptor ref params take precedence), and that the
      * Interceptor.init() method is called on the Interceptor instance before it is returned.
      *
-     * @param interceptorConfig the InterceptorConfig from the configuration
+     * @param interceptorConfig    the InterceptorConfig from the configuration
      * @param interceptorRefParams a Map of params provided in the Interceptor reference in the Action mapping or
-     * InterceptorStack definition
+     *                             InterceptorStack definition
      */
     public Interceptor buildInterceptor(InterceptorConfig interceptorConfig, Map interceptorRefParams) throws ConfigurationException {
         Interceptor interceptor = null;
         params.putAll(interceptorRefParams);
 
         try {
-            interceptor = (Interceptor) interceptorClass.newInstance();
+            interceptor = (Interceptor) buildBean(interceptorClass);
             OgnlUtil.setProperties(params, interceptor);
             interceptor.init();
 
 
     /**
      * Build a Result using the type in the ResultConfig and set the parameters in the ResultConfig.
-     *
-     * @param resultConfig
      */
     public Result buildResult(ResultConfig resultConfig) throws Exception {
         Class resultClass = resultConfig.getClazz();
         Result result = null;
 
         if (resultClass != null) {
-            result = (Result) resultClass.newInstance();
+            result = (Result) buildBean(resultClass);
             OgnlUtil.setProperties(resultConfig.getParams(), result, ActionContext.getContext().getContextMap());
         }
 
 
     /**
      * Build a Validator of the given type and set the parameters on it
-     * @param clazz the type of Validator to build
+     *
+     * @param clazz  the type of Validator to build
      * @param params property name -> value Map to set onto the Validator instance
      */
     public Validator buildValidator(Class clazz, Map params) throws Exception {
-        Validator validator = (Validator) clazz.newInstance();
+        Validator validator = (Validator) buildBean(clazz);
         OgnlUtil.setProperties(params, validator);
 
         return validator;

File src/java/com/opensymphony/xwork/interceptor/AroundInterceptor.java

 
 
 /**
- * AroundInterceptor
+ * An abstract interceptor that provides simple access to before/after callouts.
  *
  * @author Jason Carreira
  */
         return result;
     }
 
+    /**
+     * Called after the invocation has been executed.
+     *
+     * @param result the result value returned by the invocation
+     */
     protected abstract void after(ActionInvocation dispatcher, String result) throws Exception;
 
+    /**
+     * Called before the invocation has been executed. 
+     */
     protected abstract void before(ActionInvocation invocation) throws Exception;
 }

File src/java/com/opensymphony/xwork/interceptor/Interceptor.java

 
 
 /**
- * Interceptors follow the paradigm of {@link javax.servlet.Filter}. Interceptors should be stateless and not assume that
- * a new instance will be created for each request or Action. Interceptors may choose to either short-circuit the
- * DefaultActionInvocation execution and return a return code (such as Action.SUCCESS), or it may choose to do some processing
- * before and/or after delegating the rest of the procesing using DefaultActionInvocation.doInterceptor().
+ * An interceptor is a stateless class that follows the interceptor pattern, as found in {@link  javax.filter.Filter}
+ * and in AOP languages.
+ * <p/>
+ * Interceptors <b>must</b> be stateless and not assume that a new instance will be created for each request or Action.
+ * Interceptors may choose to either short-circuit the {@link ActionInvocation} execution and return a return code
+ * (such as {@link com.opensymphony.xwork.Action.SUCCESS}), or it may choose to do some processing before
+ * and/or after delegating the rest of the procesing using {@link ActionInvocation#invoke()}.
  *
- * @author $author$
- * @version $Revision$
+ * @author Jason Carreira
  */
 public interface Interceptor {
     //~ Methods ////////////////////////////////////////////////////////////////
 
     /**
-    * Called to let an interceptor clean up any resources it has allocated.
-    */
+     * Called to let an interceptor clean up any resources it has allocated.
+     */
     void destroy();
 
     /**
-    * Called after an Interceptor is created, but before any requests are processed using the intercept() methodName. This
-    * gives the Interceptor a chance to initialize any needed resources.
-    */
+     * Called after an interceptor is created, but before any requests are processed using
+     * {@link #intercept(com.opensymphony.xwork.ActionInvocation) intercept} , giving
+     * the Interceptor a chance to initialize any needed resources.
+     */
     void init();
 
     /**
-    * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
-    * request by the DefaultActionInvocation or to short-circuit the processing and just return a String return code.
-    *
-    * @param invocation
-    * @return
-    * @throws Exception
-    */
+     * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
+     * request by the {@link ActionInvocation} or to short-circuit the processing and just return a String return code.
+     *
+     * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself.
+     * @throws Exception any system-level error, as definied in {@link com.opensymphony.xwork.Action#execute()}.
+     */
     String intercept(ActionInvocation invocation) throws Exception;
 }

File src/java/com/opensymphony/xwork/interceptor/ParametersInterceptor.java

 
 
 /**
- * @author $Author$
- * @version $Revision$
+ * An interceptor that gets the parameters Map from the action context and calls
+ * {@link OgnlValueStack#setValue(java.lang.String, java.lang.Object) setValue} on
+ * the value stack with the property name being the key in the map, and the value
+ * being the associated value in the map.
+ *
+ * This interceptor sets up a few special conditions before setting the values on
+ * the stack:
+ *
+ * <ul>
+ *  <li>It turns on null object handling, meaning if the property "foo" is null and
+ *      value is set on "foo.bar", then the foo object will be created as explained
+ *      in {@link InstantiatingNullHandler}.</li>
+ *  <li>It also turns off the ability to allow methods to be executed, which is done
+ *      as a security protection. This includes both static and non-static methods,
+ *      as explained in {@link XWorkMethodAccessor}.</li>
+ *  <li>Turns on reporting of type conversion errors, which are otherwise not normally
+ *      reported. It is important to report them here because this input is expected
+*       to be directly from the user.</li>
+ * </ul>
+ *
+ * @author Patrick Lightbody
  */
 public class ParametersInterceptor extends AroundInterceptor {
     //~ Methods ////////////////////////////////////////////////////////////////

File src/java/com/opensymphony/xwork/util/InstantiatingNullHandler.java

 package com.opensymphony.xwork.util;
 
 import com.opensymphony.util.FileManager;
-
 import com.opensymphony.xwork.ObjectFactory;
-
-import ognl.*;
+import ognl.NullHandler;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import java.io.InputStream;
-
 import java.lang.reflect.Method;
-
 import java.util.*;
 
 
 /**
+ * Normally does nothing, but if {@link #CREATE_NULL_OBJECTS} is in the action context
+ * with a value of true, then this class will attempt to create null objects when Ognl
+ * requests null objects be created.
  *
- * @author $Id$
- * @version $Revision$
+ * The following rules are used:
+ * <ul>
+ *  <li>If the null property is a simple bean with a no-arg constructor, it will simply be
+ *      created using ObjectFactory's {@link ObjectFactory#buildBean(java.lang.Class) buildBean} method.</li>
+ *  <li>If the property is declared <i>exactly</i> as a {@link Collection} or {@link List}, then this class
+ *      will look in the conversion property file (see {@link XWorkConverter}) for an entry
+ *      with a key of the form "Collection_[propertyName]". Using the value of this key as
+ *      the class type in which the collection will be holding, an {@link XWorkList} will be
+ *      created, allowing simple dynamic insertion.</li>
+ *  <li>If the property is declared as a {@link Map}, then the same rules are applied for
+ *      list, except that an {@link XWorkMap} will be created instead.</li>
+ * </ul>
+ *
+ * @author Matt Ho
+ * @author Patrick Lightbody
  */
 public class InstantiatingNullHandler implements NullHandler {
     //~ Static fields/initializers /////////////////////////////////////////////
 
     public static final String CREATE_NULL_OBJECTS = "xwork.NullHandler.createNullObjects";
 
+    private static final Log LOG = LogFactory.getLog(InstantiatingNullHandler.class);
+
     //~ Instance fields ////////////////////////////////////////////////////////
 
     HashMap mappings = new HashMap();
         return null;
     }
 
-    /**
-     * @see NullHandler#nullPropertyValue(Map, Object, Object) for additional documentation
-     * @param context
-     * @param target
-     * @param property
-     * @return
-     */
     public Object nullPropertyValue(Map context, Object target, Object property) {
         Boolean create = (Boolean) context.get(CREATE_NULL_OBJECTS);
         boolean c = ((create == null) ? false : create.booleanValue());
         try {
             Class clazz = method.getParameterTypes()[0];
             Object param = createObject(context, clazz, target, property.toString());
-            method.invoke(target, new Object[] {param});
+            method.invoke(target, new Object[]{param});
 
             return param;
         } catch (Exception e) {
-            e.printStackTrace();
+            LOG.error("Could not create and/or set value back on to object", e);
         }
 
         return null;
     /**
      * Attempt to find the setter associated with the provided instance and propertyName.  If we do find it, place that
      * Method into the methodMap keyed by property name
-     * @param methodMap
+     *
      * @param propertyName the name of the property we're looking up
      * @param instance of instance of the Class we're attempting to find the setter for
-     * @return
      */
     private Method getMethod(Map methodMap, String propertyName, Object instance) {
         synchronized (methodMap) {
 
     /**
      * returns the Map associated with a given Class of Objects
+     *
      * @param instance an instance of the Class we're interested in
      * @return a Map of Method instances keyed by property name
      */
             mapping.putAll(props);
 
             for (Iterator iterator = mapping.entrySet().iterator();
-                    iterator.hasNext();) {
+                 iterator.hasNext();) {
                 Map.Entry entry = (Map.Entry) iterator.next();
                 String propName = (String) entry.getKey();
                 String className = (String) entry.getValue();

File src/java/com/opensymphony/xwork/util/OgnlValueStack.java

  * earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending
  * on the expression being evaluated).
  *
- * @author $Author$
- * @version $Revision$
+ * @author Patrick Lightbody
  */
 public class OgnlValueStack implements Serializable {
     //~ Static fields/initializers /////////////////////////////////////////////

File src/java/com/opensymphony/xwork/util/XWorkList.java

 
 
 /**
- * User: plightbo
- * Date: Jan 13, 2004
- * Time: 7:02:33 PM
+ * A simple list that when requested an index that it doesn't yet hold will
+ * create empty beans all the way up to and including that index using
+ * ObjectFactory's {@link ObjectFactory#buildBean(java.lang.Class) buildBean} method.
+ *
+ * @author Patrick Lightbody
  */
 public class XWorkList extends ArrayList {
     //~ Instance fields ////////////////////////////////////////////////////////
             try {
                 this.add(ObjectFactory.getObjectFactory().buildBean(clazz));
             } catch (Exception e) {
-                e.printStackTrace();
                 throw new RuntimeException(e.getMessage());
             }
         }

File src/java/com/opensymphony/xwork/util/XWorkMap.java

 
 
 /**
- * User: plightbo
- * Date: Jan 13, 2004
- * Time: 9:21:03 PM
+ * A simple map that when requested a key that it doesn't yet hold will
+ * create an empty beans using ObjectFactory's
+ * {@link ObjectFactory#buildBean(java.lang.Class) buildBean} method.
+ *
+ * @author Patrick Lightbody
  */
 public class XWorkMap extends HashMap {
     //~ Instance fields ////////////////////////////////////////////////////////
                 o = ObjectFactory.getObjectFactory().buildBean(clazz);
                 this.put(key, o);
             } catch (Exception e) {
-                e.printStackTrace();
                 throw new RuntimeException(e.getMessage());
             }
         }

File src/java/com/opensymphony/xwork/util/XWorkMethodAccessor.java

 
 
 /**
- * User: plightbo
- * Date: Dec 28, 2003
- * Time: 8:34:20 PM
+ * Allows methods to be executed under normal cirumstances, except when {@link #DENY_METHOD_EXECUTION}
+ * is in the action context with a value of true.  
+ *
+ * @author Patrick Lightbody
  */
 public class XWorkMethodAccessor extends ObjectMethodAccessor {
     //~ Static fields/initializers /////////////////////////////////////////////
     //~ Methods ////////////////////////////////////////////////////////////////
 
     public Object callMethod(Map context, Object object, String string, Object[] objects) throws MethodFailedException {
-        Boolean create = (Boolean) context.get(DENY_METHOD_EXECUTION);
-        boolean c = ((create == null) ? false : create.booleanValue());
+        Boolean exec = (Boolean) context.get(DENY_METHOD_EXECUTION);
+        boolean e = ((exec == null) ? false : exec.booleanValue());
 
-        if (!c) {
+        if (!e) {
             return super.callMethod(context, object, string, objects);
         } else {
             return null;
     }
 
     public Object callStaticMethod(Map context, Class aClass, String string, Object[] objects) throws MethodFailedException {
-        Boolean create = (Boolean) context.get(DENY_METHOD_EXECUTION);
-        boolean c = ((create == null) ? false : create.booleanValue());
+        Boolean exec = (Boolean) context.get(DENY_METHOD_EXECUTION);
+        boolean e = ((exec == null) ? false : exec.booleanValue());
 
-        if (!c) {
+        if (!e) {
             return super.callStaticMethod(context, aClass, string, objects);
         } else {
             return null;