struts-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From craig...@locus.apache.org
Subject cvs commit: jakarta-struts/src/share/org/apache/struts/util BeanUtils.java PropertyUtils.java
Date Sat, 23 Sep 2000 22:51:48 GMT
craigmcc    00/09/23 15:51:48

  Modified:    src/share/org/apache/struts/action Action.java
                        ActionBase.java ActionMapping.java
                        ActionServlet.java
               src/share/org/apache/struts/util BeanUtils.java
                        PropertyUtils.java
  Log:
  Make Action into a base class, rather than an interface, to minimize the
  pain of future enhancements to its functionality.  Add a variant of the
  perform() method that takes ServletRequest and ServletResponse arguments.
  
  Deprecate ActionBase -- 1.0-based applications should extend Action
  instead.
  
  Move responsibility for creating Action instances from the ActionMapping
  implementation to the controller servlet itself.
  
  Provide "lifecycle" support to Action instances (in preparation for
  supporting the ability to "reload" an application's configuration files),
  via the setServlet() method.  This is called with a non-null argument
  identifying the owning ActionServlet instance when the Action is first
  created, and called with a null argument before shutdown, allowing any
  necessary resource cleanup to take place.
  
  Remove "servlet" from the set of parameters for perform(), since it is now
  set via the lifecycle functionality above.
  
  Revision  Changes    Path
  1.5       +195 -11   jakarta-struts/src/share/org/apache/struts/action/Action.java
  
  Index: Action.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Action.java	2000/09/20 04:20:21	1.4
  +++ Action.java	2000/09/23 22:51:45	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.4
2000/09/20 04:20:21 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/09/20 04:20:21 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.5
2000/09/23 22:51:45 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/09/23 22:51:45 $
    *
    * ====================================================================
    *
  @@ -64,9 +64,16 @@
   
   
   import java.io.IOException;
  +import java.util.Locale;
   import javax.servlet.ServletException;
  +import javax.servlet.ServletRequest;
  +import javax.servlet.ServletResponse;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  +import javax.servlet.http.HttpSession;
  +import org.apache.struts.taglib.Constants;
  +import org.apache.struts.util.ErrorMessages;
  +import org.apache.struts.util.MessageResources;
   
   
   /**
  @@ -82,18 +89,26 @@
    * <ul>
    * <li>Instance and static variables MUST NOT be used to store information
    *     related to the state of a particular request.  They MAY be used to
  - *     share global resources across requests for the same action.
  + *     share global resources across requests for the same action.</li>
    * <li>Access to other resources (JavaBeans, session variables, etc.) MUST
    *     be synchronized if those resources require protection.  (Generally,
    *     however, resource classes should be designed to provide their own
  - *     protection where necessary.
  + *     protection where necessary.</li>
    * </ul>
  + * <p>
  + * When an <code>Action</code> instance is first created, the controller
  + * servlet will call <code>setServlet()</code> with a non-null argument to
  + * identify the controller servlet instance to which this Action is attached.
  + * When the controller servlet is to be shut down (or restarted), the
  + * <code>setServlet()</code> method will be called with a <code>null</code>
  + * argument, which can be used to clean up any allocated resources in use
  + * by this Action.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2000/09/20 04:20:21 $
  + * @version $Revision: 1.5 $ $Date: 2000/09/23 22:51:45 $
    */
   
  -public interface Action {
  +public class Action {
   
   
       // ----------------------------------------------------- Manifest Constants
  @@ -155,17 +170,93 @@
         "org.apache.struts.action.MESSAGE";
   
   
  +    // ----------------------------------------------------- Instance Variables
  +
  +
  +    /**
  +     * The system default Locale.
  +     */
  +    protected static Locale defaultLocale = Locale.getDefault();
  +
  +
  +    /**
  +     * The controller servlet to which we are attached.
  +     */
  +    protected ActionServlet servlet = null;
  +
  +
  +    // ------------------------------------------------------------- Properties
  +
  +
  +    /**
  +     * Return the controller servlet instance to which we are attached.
  +     */
  +    public ActionServlet getServlet() {
  +
  +        return (this.servlet);
  +
  +    }
  +
  +
  +    /**
  +     * Set the controller servlet instance to which we are attached (if
  +     * <code>servlet</code> is non-null), or release any allocated resources
  +     * (if <code>servlet</code> is null).
  +     *
  +     * @param servlet The new controller servlet, if any
  +     */
  +    public void setServlet(ActionServlet servlet) {
  +
  +        this.servlet = servlet;
  +
  +    }
  +
  +
       // --------------------------------------------------------- Public Methods
   
   
       /**
  +     * Process the specified non-HTTP request, and create the corresponding
  +     * non-HTTP response (or forward to another web component that will create
  +     * it).  Return an <code>ActionForward</code> instance describing where
  +     * and how control should be forwarded, or <code>null</code> if the
  +     * response has already been completed.
  +     * <p>
  +     * The default implementation attempts to forward to the HTTP version of
  +     * this method.
  +     *
  +     * @param mapping The ActionMapping used to select this instance
  +     * @param actionForm The optional ActionForm bean for this request (if any)
  +     * @param request The non-HTTP request we are processing
  +     * @param response The non-HTTP response we are creating
  +     *
  +     * @exception IOException if an input/output error occurs
  +     * @exception ServletException if a servlet exception occurs
  +     */
  +    public ActionForward perform(ActionMapping mapping,
  +                                 ActionForm form,
  +                                 ServletRequest request,
  +                                 ServletResponse response)
  +        throws IOException, ServletException {
  +
  +        try {
  +            return (perform(mapping, form,
  +                            (HttpServletRequest) request,
  +                            (HttpServletResponse) response));
  +        } catch (ClassCastException e) {
  +            return (null);
  +        }
  +
  +    }
  +
  +
  +    /**
        * Process the specified HTTP request, and create the corresponding HTTP
        * response (or forward to another web component that will create it).
        * Return an <code>ActionForward</code> instance describing where and how
        * control should be forwarded, or <code>null</code> if the response has
        * already been completed.
        *
  -     * @param servlet The ActionServlet making this request
        * @param mapping The ActionMapping used to select this instance
        * @param actionForm The optional ActionForm bean for this request (if any)
        * @param request The HTTP request we are processing
  @@ -174,12 +265,105 @@
        * @exception IOException if an input/output error occurs
        * @exception ServletException if a servlet exception occurs
        */
  -    public ActionForward perform(ActionServlet servlet,
  -				 ActionMapping mapping,
  +    public ActionForward perform(ActionMapping mapping,
   				 ActionForm form,
   				 HttpServletRequest request,
   				 HttpServletResponse response)
  -	throws IOException, ServletException;
  +	throws IOException, ServletException {
  +
  +        return (null);  // Override this method to provide functionality
  +
  +    }
  +
  +
  +    // ---------------------------------------------------- Protected Methods
  +
  +
  +    /**
  +     * Return the user's currently selected Locale.
  +     *
  +     * @param request The request we are processing
  +     */
  +    protected Locale getLocale(HttpServletRequest request) {
  +
  +	HttpSession session = request.getSession();
  +	Locale locale = (Locale) session.getAttribute(LOCALE_KEY);
  +	if (locale == null)
  +	    locale = defaultLocale;
  +	return (locale);
  +
  +    }
  +
  +
  +    /**
  +     * Set the user's currently selected Locale.
  +     *
  +     * @param request The request we are processing
  +     * @param locale The user's selected Locale to be set, or null
  +     *  to select the server's default Locale
  +     */
  +    protected void setLocale(HttpServletRequest request, Locale locale) {
  +
  +	HttpSession session = request.getSession();
  +	if (locale == null)
  +	    locale = defaultLocale;
  +	session.setAttribute(LOCALE_KEY, locale);
  +
  +    }
  +
  +
  +    /**
  +     * Return the message resources for this application.
  +     */
  +    protected MessageResources getResources() {
  +
  +	return (servlet.getResources());
  +
  +    }
  +
  +
  +    /**
  +     * Returns <code>true</code> if the form cancel button was pressed.
  +     * This method will check if the cancel button generated by
  +     * <strong>CancelTag</strong> was pressed by the user in the
  +     * current request.  If true, validation by any
  +     * <strong>ValidatingActionForm</strong> validate() method will be
  +     * skipped.
  +     *
  +     * @param request The servlet request we are processing
  +     * @see org.apache.struts.taglib.CancelTag
  +     * @see org.apache.struts.action.ValidatingActionForm
  +     */
  +    protected boolean isCancelled(HttpServletRequest request) {
  +
  +	return (request.getParameter(Constants.CANCEL_PROPERTY) != null);
  +
  +    }
  +
  +
  +    /**
  +     * Save the specified error messages keys into the appropriate request
  +     * attribute for use by the &lt;struts:errors&gt; tag, if any messages
  +     * are required.  Otherwise, ensure that the request attribute is not
  +     * created.
  +     *
  +     * @param request The servlet request we are processing
  +     * @param messages Vector containing message keys for looking
  +     *  up errors in the application resources
  +     */
  +    protected void saveErrors(HttpServletRequest request,
  +			      ErrorMessages messages) {
  +
  +	// Remove any error messages attribute if none are required
  +	if ((messages == null) || (messages.getSize() == 0)) {
  +	    request.removeAttribute(ERROR_KEY);
  +	    return;
  +	}
  +
  +	// Save the error messages we need
  +	request.setAttribute(ERROR_KEY, messages.getErrors());
  +
  +    }
   
   
   }
  
  
  
  1.8       +8 -144    jakarta-struts/src/share/org/apache/struts/action/ActionBase.java
  
  Index: ActionBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionBase.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ActionBase.java	2000/08/13 03:43:39	1.7
  +++ ActionBase.java	2000/09/23 22:51:45	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionBase.java,v
1.7 2000/08/13 03:43:39 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2000/08/13 03:43:39 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionBase.java,v
1.8 2000/09/23 22:51:45 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2000/09/23 22:51:45 $
    *
    * ====================================================================
    *
  @@ -63,154 +63,18 @@
   package org.apache.struts.action;
   
   
  -import java.io.IOException;
  -import java.util.Locale;
  -import javax.servlet.ServletException;
  -import javax.servlet.http.HttpServletRequest;
  -import javax.servlet.http.HttpServletResponse;
  -import javax.servlet.http.HttpSession;
  -import org.apache.struts.taglib.Constants;
  -import org.apache.struts.util.ErrorMessages;
  -import org.apache.struts.util.MessageResources;
  -
  -
   /**
    * Abstract basic implementation of <strong>Action</strong> that provides
    * useful utility methods for use by Action classes.
    *
  + * @deprecated Application action classes should now extend Action
  + * directly, rather than this class.
  + *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2000/08/13 03:43:39 $
  + * @version $Revision: 1.8 $ $Date: 2000/09/23 22:51:45 $
    */
  -
  -public abstract class ActionBase implements Action {
  -
  -
  -    // --------------------------------------------------- Instance Variables
  -
  -
  -    /**
  -     * The system default Locale.
  -     */
  -    protected static Locale defaultLocale = Locale.getDefault();
  -
  -
  -    // ------------------------------------------------------- Public Methods
  -
  -
  -    /**
  -     * Process the specified HTTP request, and create the corresponding HTTP
  -     * response (or forward to another web component that will create it).
  -     * Return an <code>ActionForward</code> instance describing where and how
  -     * control should be forwarded, or <code>null</code> if the response has
  -     * already been completed.
  -     *
  -     * @param servlet The ActionServlet making this request
  -     * @param mapping The ActionMapping used to select this instance
  -     * @param actionForm The optional ActionForm bean for this request (if any)
  -     * @param request The HTTP request we are processing
  -     * @param response The HTTP response we are creating
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  -     */
  -    public abstract ActionForward perform(ActionServlet servlet,
  -					  ActionMapping mapping,
  -					  ActionForm form,
  -					  HttpServletRequest request,
  -					  HttpServletResponse response)
  -	throws IOException, ServletException;
  -
  -
  -    // ---------------------------------------------------- Protected Methods
  -
  -
  -    /**
  -     * Return the user's currently selected Locale.
  -     *
  -     * @param request The request we are processing
  -     */
  -    protected Locale getLocale(HttpServletRequest request) {
  -
  -	HttpSession session = request.getSession();
  -	Locale locale = (Locale) session.getAttribute(LOCALE_KEY);
  -	if (locale == null)
  -	    locale = defaultLocale;
  -	return (locale);
  -
  -    }
  -
  -
  -    /**
  -     * Set the user's currently selected Locale.
  -     *
  -     * @param request The request we are processing
  -     * @param locale The user's selected Locale to be set, or null
  -     *  to select the server's default Locale
  -     */
  -    protected void setLocale(HttpServletRequest request, Locale locale) {
  -
  -	HttpSession session = request.getSession();
  -	if (locale == null)
  -	    locale = defaultLocale;
  -	session.setAttribute(LOCALE_KEY, locale);
  -
  -    }
  -
  -
  -    /**
  -     * Return the message resources for this application.
  -     *
  -     * @param servlet The action servlet for this request
  -     */
  -    protected MessageResources getResources(ActionServlet servlet) {
  -
  -	return (servlet.getResources());
  -
  -    }
  -
  -
  -    /**
  -     * Returns <code>true</code> if the form cancel button was pressed.
  -     * This method will check if the cancel button generated by
  -     * <strong>CancelTag</strong> was pressed by the user in the
  -     * current request.  If true, validation by any
  -     * <strong>ValidatingActionForm</strong> validate() method will be
  -     * skipped.
  -     *
  -     * @param request The servlet request we are processing
  -     * @see org.apache.struts.taglib.CancelTag
  -     * @see org.apache.struts.action.ValidatingActionForm
  -     */
  -    protected boolean isCancelled(HttpServletRequest request) {
  -
  -	return (request.getParameter(Constants.CANCEL_PROPERTY) != null);
  -
  -    }
  -
  -
  -    /**
  -     * Save the specified error messages keys into the appropriate request
  -     * attribute for use by the &lt;struts:errors&gt; tag, if any messages
  -     * are required.  Otherwise, ensure that the request attribute is not
  -     * created.
  -     *
  -     * @param request The servlet request we are processing
  -     * @param messages Vector containing message keys for looking
  -     *  up errors in the application resources
  -     */
  -    protected void saveErrors(HttpServletRequest request,
  -			      ErrorMessages messages) {
  -
  -	// Remove any error messages attribute if none are required
  -	if ((messages == null) || (messages.getSize() == 0)) {
  -	    request.removeAttribute(ERROR_KEY);
  -	    return;
  -	}
  -
  -	// Save the error messages we need
  -	request.setAttribute(ERROR_KEY, messages.getErrors());
   
  -    }
  +public class ActionBase extends Action {
   
   
   }
  
  
  
  1.8       +4 -27     jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java
  
  Index: ActionMapping.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ActionMapping.java	2000/09/20 04:20:21	1.7
  +++ ActionMapping.java	2000/09/23 22:51:46	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v
1.7 2000/09/20 04:20:21 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2000/09/20 04:20:21 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v
1.8 2000/09/23 22:51:46 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2000/09/23 22:51:46 $
    *
    * ====================================================================
    *
  @@ -138,7 +138,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2000/09/20 04:20:21 $
  + * @version $Revision: 1.8 $ $Date: 2000/09/23 22:51:46 $
    */
   
   public class ActionMapping {
  @@ -647,29 +647,6 @@
       public void addForward(ActionForward forward) {
   
           forwards.addForward(forward);
  -
  -    }
  -
  -
  -    /**
  -     * Return an initialized instance of our Action class for this mapping.
  -     * If instantiation fails for any reason, <code>null</code> is returned.
  -     */
  -    public Action createActionInstance() {
  -
  -        // Return the already instantiated instance (if any)
  -        if (instance != null)
  -            return (instance);
  -
  -        // Instantiate and return a new instance of the Action class
  -        try {
  -            Class clazz = Class.forName(type);
  -            instance = (Action) clazz.newInstance();
  -        } catch (Throwable t) {
  -            instance = null;
  -        }
  -
  -        return (instance);
   
       }
   
  
  
  
  1.23      +84 -25    jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java
  
  Index: ActionServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- ActionServlet.java	2000/09/23 19:17:10	1.22
  +++ ActionServlet.java	2000/09/23 22:51:46	1.23
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
1.22 2000/09/23 19:17:10 craigmcc Exp $
  - * $Revision: 1.22 $
  - * $Date: 2000/09/23 19:17:10 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
1.23 2000/09/23 22:51:46 craigmcc Exp $
  + * $Revision: 1.23 $
  + * $Date: 2000/09/23 22:51:46 $
    *
    * ====================================================================
    *
  @@ -67,8 +67,10 @@
   import java.io.IOException;
   import java.net.URL;
   import java.util.Hashtable;
  +import java.util.Enumeration;
   import java.util.Locale;
   import java.util.MissingResourceException;
  +import java.util.Vector;
   import javax.servlet.RequestDispatcher;
   import javax.servlet.ServletException;
   import javax.servlet.UnavailableException;
  @@ -197,7 +199,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.22 $ $Date: 2000/09/23 19:17:10 $
  + * @version $Revision: 1.23 $ $Date: 2000/09/23 22:51:46 $
    */
   
   public class ActionServlet
  @@ -208,6 +210,13 @@
   
   
       /**
  +     * The set of Action instances that have been created and initialized,
  +     * keyed by the fully qualified Java class name.
  +     */
  +    protected Hashtable actions = new Hashtable();
  +
  +
  +    /**
        * The resources object for our application resources (if any).
        */
       protected MessageResources application = null;
  @@ -324,6 +333,7 @@
   	if (debug >= 1)
   	    log(internal.getMessage("finalizing"));
   
  +        destroyActions();
   	destroyApplication();
   	destroyInternal();
   
  @@ -600,6 +610,24 @@
   
   
       /**
  +     * Gracefully shut down any action instances we have created.
  +     */
  +    protected void destroyActions() {
  +
  +        synchronized (this.actions) {
  +            Vector actives = new Vector();
  +            Enumeration actions = this.actions.elements();
  +            while (actions.hasMoreElements()) {
  +                Action action = (Action) actions.nextElement();
  +                action.setServlet(null);
  +            }
  +            this.actions.clear();
  +        }
  +
  +    }
  +
  +
  +    /**
        * Gracefully terminate use of the application MessageResources (if any).
        */
       protected void destroyApplication() {
  @@ -973,9 +1001,50 @@
   	if (!processValidate(mapping, formInstance, request, response))
   	    return;
   
  +        // Acquire the Action instance to process this request
  +        Action actionInstance = processActionCreate(mapping, request);
  +        if (actionInstance == null) {
  +            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  +                               internal.getMessage("actionCreate",
  +                                                   mapping.getPath()));
  +            return;
  +        }
  +
   	// Call the action instance itself
  -	processActionInstance(mapping, formInstance, request, response);
  +	processActionPerform(actionInstance, mapping, formInstance,
  +                             request, response);
  +
  +    }
  +
  +
  +    /**
  +     * Create or retrieve the Action instance that will process this request,
  +     * or <code>null</code> if no such Action instance can be created.
  +     *
  +     * @param mapping The ActionMapping we are processing
  +     * @param request The servlet request we are processing
  +     */
  +    protected Action processActionCreate(ActionMapping mapping,
  +                                         HttpServletRequest request) {
   
  +        // Acquire the Action instance we will be using
  +        String actionClass = mapping.getActionClass();
  +        Action actionInstance = (Action) actions.get(actionClass);
  +        if (actionInstance == null) {
  +            try {
  +                Class clazz = Class.forName(actionClass);
  +                actionInstance = (Action) clazz.newInstance();
  +                actionInstance.setServlet(this);
  +                actions.put(actionClass, actionInstance);
  +            } catch (Throwable t) {
  +                log("Error creating Action instance for path '" +
  +                    mapping.getPath() + "', class name '" +
  +                    actionClass + "'", t);
  +                return (null);
  +            }
  +        }
  +        return (actionInstance);
  +
       }
   
   
  @@ -1035,9 +1104,9 @@
   
   
       /**
  -     * Identify and call an appropriate <code>Action</code> instance
  -     * to handle this request.
  +     * Ask the specified Action instance to handle this request.
        *
  +     * @param action The Action to process this request
        * @param mapping The ActionMapping we are processing
        * @param formInstance The ActionForm we are processing
        * @param request The servlet request we are processing
  @@ -1046,28 +1115,18 @@
        * @exception IOException if an input/output error occurs
        * @exception ServletException if a servlet exception occurs
        */
  -    protected void processActionInstance(ActionMapping mapping,
  -					 ActionForm formInstance,
  -					 HttpServletRequest request,
  -					 HttpServletResponse response)
  +    protected void processActionPerform(Action action,
  +                                        ActionMapping mapping,
  +                                        ActionForm formInstance,
  +                                        HttpServletRequest request,
  +                                        HttpServletResponse response)
   	throws IOException, ServletException {
   
  -	// Identify the action class we will be using
  -	Action actionInstance = mapping.createActionInstance();
  -	if (actionInstance == null) {
  -	    if (debug >= 1)
  -	        log("Could not create an ActionInstance for '" +
  -		    mapping.getPath() + "'");
  -	    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -			       internal.getMessage("actionCreate",
  -						   mapping.getPath()));
  -	    return;
  -	}
  -
   	// Perform the requested action
   	ActionForward forward =
  -	    actionInstance.perform(this, mapping, formInstance,
  -				   request, response);
  +	    action.perform(mapping, formInstance, request, response);
  +
  +        // Obey any returned ActionForward
   	if (forward != null) {
   	    String path = forward.getPath();
   	    if (forward.getRedirect())
  
  
  
  1.12      +37 -67    jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java
  
  Index: BeanUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- BeanUtils.java	2000/08/31 00:11:16	1.11
  +++ BeanUtils.java	2000/09/23 22:51:47	1.12
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java,v
1.11 2000/08/31 00:11:16 craigmcc Exp $
  - * $Revision: 1.11 $
  - * $Date: 2000/08/31 00:11:16 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/BeanUtils.java,v
1.12 2000/09/23 22:51:47 craigmcc Exp $
  + * $Revision: 1.12 $
  + * $Date: 2000/09/23 22:51:47 $
    *
    * ====================================================================
    *
  @@ -84,22 +84,12 @@
    * @author Craig R. McClanahan
    * @author Ralph Schaer
    * @author Chris Audley
  - * @version $Revision: 1.11 $ $Date: 2000/08/31 00:11:16 $
  + * @version $Revision: 1.12 $ $Date: 2000/09/23 22:51:47 $
    */
   
   public final class BeanUtils {
   
   
  -    // ------------------------------------------------------- Static Variables
  -
  -
  -    /**
  -     * The cache of PropertyDescriptor arrays for beans we have already
  -     * introspected, keyed by the fully qualified class name of this bean.
  -     */
  -    private static Hashtable descriptorsCache = new Hashtable();
  -
  -
       // --------------------------------------------------------- Public Classes
   
   
  @@ -339,7 +329,7 @@
   	throws IllegalAccessException, InvocationTargetException,
   	       NoSuchMethodException {
   
  -	Object value = getPropertyValue(bean, name);
  +	Object value = PropertyUtils.getProperty(bean, name);
   	if (value == null) {
   	    return (null);
   	} else if (value.getClass().isArray()) {
  @@ -367,6 +357,10 @@
        * property, as a String.  The index is specified by being appended
        * to the property name in square brackets.  If the specified index
        * is out of range, <code>null</code> is returned.
  +     * <p>
  +     * <strong>WARNING</strong> - Use of the "square brackets" syntax
  +     * for indexed references has been deprecated in favor of the new
  +     * approach using the PropertyUtils.INDEXED_DELIM delimiter
        *
        * @param bean Bean whose property is to be extracted
        * @param name name of the property to be extracted, plus a literal
  @@ -383,15 +377,21 @@
   	throws IllegalAccessException, InvocationTargetException,
   	       NoSuchMethodException {
   
  -	// Parse the property name and subscript expression
  +        // @deprecated Convert the deprecated syntax to the new format
   	int left = name.lastIndexOf("[");
   	int right = name.lastIndexOf("]");
  -	if ((left < 0) || (right < left) ||
  -	    (right < (name.length() - 1)))
  +        if ((left >= 0) && (right > left))
  +            name = name.substring(0, left) + PropertyUtils.INDEXED_DELIM +
  +                name.substring(left + 1, right);
  +
  +	// Parse the property name and subscript expression
  +        int delim = PropertyUtils.INDEXED_DELIM;
  +        if (delim < 0)
   	    return (getScalarProperty(bean, name));
   	int index = -1;
   	try {
  -	    index = Integer.parseInt(name.substring(left + 1, right));
  +	    index = Integer.parseInt(name.substring(delim + 1));
  +            name = name.substring(0, delim);
   	} catch (NumberFormatException e) {
   	    return (getScalarProperty(bean, name));
   	}
  @@ -441,20 +441,18 @@
        *
        * @param bean The JavaBean that the property belongs to
        * @param name Name of the property whose setter method is requested
  +     *
  +     * @deprecated Use <code>PropertyUtils.getPropertyDescriptor()</code>
  +     *  instead
        */
       public static PropertyDescriptor getPropertyDescriptor(Object bean,
   							   String name) {
   
  -	if ((bean == null) || (name == null))
  -	    return (null);
  -	PropertyDescriptor descriptors[] = getPropertyDescriptors(bean);
  -	if (descriptors == null)
  -	    return (null);
  -	for (int i = 0; i < descriptors.length; i++) {
  -	    if (name.equals(descriptors[i].getName()))
  -		return (descriptors[i]);
  -	}
  -	return (null);
  +        try {
  +            return (PropertyUtils.getPropertyDescriptor(bean, name));
  +        } catch (Throwable t) {
  +            return (null);
  +        }
   
       }
   
  @@ -465,32 +463,14 @@
        * a zero-length array is returned.
        *
        * @param bean Bean whose property descriptors are required
  +     *
  +     * @deprecated Use <code>PropertyUtils.getPropertyDescriptors()</code>
  +     *  instead
        */
       public static PropertyDescriptor[] getPropertyDescriptors(Object bean) {
  -
  -	if (bean == null)
  -	    return (new PropertyDescriptor[0]);
   
  -	// Look up any cached descriptors for this bean class
  -	String beanClassName = bean.getClass().getName();
  -	PropertyDescriptor descriptors[] =
  -	    (PropertyDescriptor[]) descriptorsCache.get(beanClassName);
  -	if (descriptors != null)
  -	    return (descriptors);
  +        return (PropertyUtils.getPropertyDescriptors(bean));
   
  -	// Introspect the bean and cache the generated descriptors
  -	BeanInfo beanInfo = null;
  -	try {
  -	    beanInfo = Introspector.getBeanInfo(bean.getClass());
  -	} catch (IntrospectionException e) {
  -	    return (new PropertyDescriptor[0]);
  -	}
  -	descriptors = beanInfo.getPropertyDescriptors();
  -	if (descriptors == null)
  -	    descriptors = new PropertyDescriptor[0];
  -	descriptorsCache.put(beanClassName, descriptors);
  -	return (descriptors);
  -
       }
   
   
  @@ -507,25 +487,14 @@
        *  throws an exception
        * @exception NoSuchMethodException if an accessor method for this
        *  propety cannot be found
  +     *
  +     * @deprecated Use <code>PropertyUtils.getProperty()</code> instead.
        */
       public static Object getPropertyValue(Object bean, String name)
   	throws IllegalAccessException, InvocationTargetException,
   	       NoSuchMethodException {
   
  -	// Retrieve the property getter method for the specified property
  -	PropertyDescriptor descriptor =
  -	    getPropertyDescriptor(bean, name);
  -	if (descriptor == null)
  -	    throw new NoSuchMethodException("Unknown property '" +
  -					    name + "'");
  -	Method readMethod = descriptor.getReadMethod();
  -	if (readMethod == null)
  -	    throw new NoSuchMethodException("Property '" + name +
  -					    "' has no getter method");
  -
  -	// Call the property getter and return the value
  -	Object value = readMethod.invoke(bean, new Object[0]);
  -	return (value);
  +        return (PropertyUtils.getProperty(bean, name));
   
       }
   
  @@ -548,7 +517,7 @@
   	throws IllegalAccessException, InvocationTargetException,
   	       NoSuchMethodException {
   
  -	Object value = getPropertyValue(bean, name);
  +	Object value = PropertyUtils.getProperty(bean, name);
   	if (value == null) {
   	    return (null);
   	} else if (value.getClass().isArray()) {
  @@ -718,7 +687,8 @@
   	    return;
   
   	// Identify the property descriptors supported by our JavaBean
  -	PropertyDescriptor descriptors[] = getPropertyDescriptors(bean);
  +	PropertyDescriptor descriptors[] =
  +            PropertyUtils.getPropertyDescriptors(bean);
   	if (descriptors.length < 1)
   	    return;
   
  
  
  
  1.3       +86 -76    jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java
  
  Index: PropertyUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PropertyUtils.java	2000/09/21 03:39:34	1.2
  +++ PropertyUtils.java	2000/09/23 22:51:47	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java,v
1.2 2000/09/21 03:39:34 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/09/21 03:39:34 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/PropertyUtils.java,v
1.3 2000/09/23 22:51:47 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/09/23 22:51:47 $
    *
    * ====================================================================
    *
  @@ -99,28 +99,46 @@
    *     will have a getter method named <code>getXyz()</code> or (for boolean
    *     properties only) <code>isXyz()</code>, and a setter method named
    *     <code>setXyz()</code>.</li>
  - * <li><strong>Nested (<code>name1.name2.name3</code>)</strong>
The first
  + * <li><strong>Nested (<code>name1_name2_name3</code>)</strong>
The first
    *     name element is used to select a property getter, as for simple
    *     references above.  The object returned for this property is then
    *     consulted, using the same approach, for a property getter for a
    *     property named <code>name2</code>, and so on.  The property value that
    *     is ultimately retrieved or modified is the one identified by the
    *     last name element.</li>
  - * <li><strong>Indexed (<code>name[index]</code>)</strong>
- The underlying
  + * <li><strong>Indexed (<code>name$index</code>)</strong>
- The underlying
    *     property value is assumed to be an array, or this JavaBean is assumed
    *     to have indexed property getter and setter methods.  The appropriate
    *     (zero-relative) entry in the array is selected.</li>
  + * <li><strong>Combined (<code>name1_name2$index_name3</strong>
- Various
  + *     forms combining nested and indexed references are also supported.</li>
    * </ul>
    *
    * @author Craig R. McClanahan
    * @author Ralph Schaer
    * @author Chris Audley
  - * @version $Revision: 1.2 $ $Date: 2000/09/21 03:39:34 $
  + * @version $Revision: 1.3 $ $Date: 2000/09/23 22:51:47 $
    */
   
   public final class PropertyUtils {
   
   
  +    // ----------------------------------------------------- Manifest Constants
  +
  +
  +    /**
  +     * The delimiter that preceeds the zero-relative subscript for an
  +     * indexed reference.
  +     */
  +    public static final char INDEXED_DELIM = '$';
  +
  +
  +    /**
  +     * The delimiter that separates the components of a nested reference.
  +     */
  +    public static final char NESTED_DELIM = '_';
  +
  +
       // ------------------------------------------------------- Static Variables
   
   
  @@ -192,23 +210,19 @@
   	       NoSuchMethodException {
   
   	// Identify the index of the requested individual property
  -	int left = name.indexOf("[");
  -	int right = name.indexOf("]");
  -	if ((left < 0) || (right <= left))
  +        int delim = name.indexOf(INDEXED_DELIM);
  +        if (delim < 0)
   	    throw new IllegalArgumentException("Invalid indexed property '" +
   					       name + "'");
  -	if (right > (name.length() - 1))
  -	    throw new IllegalArgumentException("Invalid indexed property '" +
  -					       name + "'");
   	int index = -1;
   	try {
  -	    String subscript = name.substring(left + 1, right);
  +	    String subscript = name.substring(delim + 1);
   	    index = Integer.parseInt(subscript);
   	} catch (NumberFormatException e) {
   	    throw new IllegalArgumentException("Invalid indexed property '" +
   					       name + "'");
   	}
  -	name = name.substring(0, left);
  +	name = name.substring(0, delim);
   
   	// Request the specified indexed property value
   	return (getIndexedProperty(bean, name, index));
  @@ -291,22 +305,22 @@
   	       NoSuchMethodException {
   
   	while (true) {
  -	    int period = name.indexOf(".");
  -	    if (period < 0)
  +	    int delim = name.indexOf(NESTED_DELIM);
  +	    if (delim < 0)
   		break;
  -	    String next = name.substring(0, period);
  -	    if (next.indexOf("[") >= 0)
  +	    String next = name.substring(0, delim);
  +	    if (next.indexOf(INDEXED_DELIM) >= 0)
   		bean = getIndexedProperty(bean, next);
   	    else
   		bean = getSimpleProperty(bean, next);
   	    if (bean == null)
   		throw new IllegalArgumentException
   		    ("Null property value for '" +
  -		     name.substring(0, period) + "'");
  -	    name = name.substring(period + 1);
  +		     name.substring(0, delim) + "'");
  +	    name = name.substring(delim + 1);
   	}
   
  -	if (name.indexOf("[") >= 0)
  +	if (name.indexOf(INDEXED_DELIM) >= 0)
   	    return (getIndexedProperty(bean, name));
   	else
   	    return (getSimpleProperty(bean, name));
  @@ -551,52 +565,6 @@
   
   
       /**
  -     * Set the value of the (possibly nested) property of the specified
  -     * name, for the specified bean, with no type conversions.
  -     *
  -     * @param bean Bean whose property is to be modified
  -     * @param name Possibly nested name of the property to be modified
  -     * @param value Value to which the property is to be set
  -     *
  -     * @exception IllegalAccessException if the caller does not have
  -     *  access to the property accessor method
  -     * @exception IllegalArgumentException if a nested reference to a
  -     *  property returns null
  -     * @exception InvocationTargetException if the property accessor method
  -     *  throws an exception
  -     * @exception NoSuchMethodException if an accessor method for this
  -     *  propety cannot be found
  -     */
  -    public static void setNestedProperty(Object bean,
  -					 String name, Object value)
  -	throws IllegalAccessException, InvocationTargetException,
  -	       NoSuchMethodException {
  -
  -	while (true) {
  -	    int period = name.indexOf(".");
  -	    if (period < 0)
  -		break;
  -	    String next = name.substring(0, period);
  -	    if (next.indexOf("[") >= 0)
  -		bean = getIndexedProperty(bean, next);
  -	    else
  -		bean = getSimpleProperty(bean, next);
  -	    if (bean == null)
  -		throw new IllegalArgumentException
  -		    ("Null property value for '" +
  -		     name.substring(0, period) + "'");
  -	    name = name.substring(period + 1);
  -	}
  -
  -	if (name.indexOf("[") >= 0)
  -	    setIndexedProperty(bean, name, value);
  -	else
  -	    setSimpleProperty(bean, name, value);
  -
  -    }
  -
  -
  -    /**
        * Set the value of the specified indexed property of the specified
        * bean, with no type conversions.  The zero-relative index of the
        * required value must be included (in square brackets) as a suffix to
  @@ -622,25 +590,21 @@
   	       NoSuchMethodException {
   
   	// Identify the index of the requested individual property
  -	int left = name.indexOf("[");
  -	int right = name.indexOf("]");
  -	if ((left < 0) || (right <= left))
  +	int delim = name.indexOf(INDEXED_DELIM);
  +        if (delim < 0)
   	    throw new IllegalArgumentException("Invalid indexed property '" +
   					       name + "'");
  -	if (right > (name.length() - 1))
  -	    throw new IllegalArgumentException("Invalid indexed property '" +
  -					       name + "'");
   	int index = -1;
   	try {
  -	    String subscript = name.substring(left + 1, right);
  +	    String subscript = name.substring(delim + 1);
   	    index = Integer.parseInt(subscript);
   	} catch (NumberFormatException e) {
   	    throw new IllegalArgumentException("Invalid indexed property '" +
   					       name + "'");
   	}
  -	name = name.substring(0, left);
  +	name = name.substring(0, delim);
   
  -	// Request the specified indexed property value
  +	// Set the specified indexed property value
   	setIndexedProperty(bean, name, index, value);
   
       }
  @@ -701,6 +665,52 @@
   
   	// Modify the specified value
   	Array.set(array, index, value);
  +
  +    }
  +
  +
  +    /**
  +     * Set the value of the (possibly nested) property of the specified
  +     * name, for the specified bean, with no type conversions.
  +     *
  +     * @param bean Bean whose property is to be modified
  +     * @param name Possibly nested name of the property to be modified
  +     * @param value Value to which the property is to be set
  +     *
  +     * @exception IllegalAccessException if the caller does not have
  +     *  access to the property accessor method
  +     * @exception IllegalArgumentException if a nested reference to a
  +     *  property returns null
  +     * @exception InvocationTargetException if the property accessor method
  +     *  throws an exception
  +     * @exception NoSuchMethodException if an accessor method for this
  +     *  propety cannot be found
  +     */
  +    public static void setNestedProperty(Object bean,
  +					 String name, Object value)
  +	throws IllegalAccessException, InvocationTargetException,
  +	       NoSuchMethodException {
  +
  +	while (true) {
  +	    int delim = name.indexOf(NESTED_DELIM);
  +	    if (delim < 0)
  +		break;
  +	    String next = name.substring(0, delim);
  +	    if (next.indexOf(INDEXED_DELIM) >= 0)
  +		bean = getIndexedProperty(bean, next);
  +	    else
  +		bean = getSimpleProperty(bean, next);
  +	    if (bean == null)
  +		throw new IllegalArgumentException
  +		    ("Null property value for '" +
  +		     name.substring(0, delim) + "'");
  +	    name = name.substring(delim + 1);
  +	}
  +
  +	if (name.indexOf(INDEXED_DELIM) >= 0)
  +	    setIndexedProperty(bean, name, value);
  +	else
  +	    setSimpleProperty(bean, name, value);
   
       }
   
  
  
  

Mime
View raw message