sitelink1  
sitelink2  
extra_vars5  
extra_vars6  
package com.ibatis.struts;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
* BeanAction is an extension to the typical Struts Action class that
* enables mappings to bean methods.  This allows for a more typical
* Object Oriented design where each object has behaviour as part of
* its definition.  Instead of writing separate Actions and Forms,
* BeanAction allows you to simply have a Bean, which models both
* the state and the methods that operate on that state.
*
* In addition to the simpler packaging, BeanAction also simplifies the
* Struts progamming paradigm and reduces dependency on Struts.  Using
* this pattern could allow easier migration to newer frameworks like JSF.
*
* The method signatures are greatly simplified to the following
*
* public String myActionMethod() {
*   //..work
*   return "success";
* }
*
* The return parameter becomes simply the name of the forward (as defined
* in the config file as usual).  Form parameters, request, response, session,
* attributes, and cookies are all accessed via the ActionContext class (see the
* ActionContext javadocs for more).
*
* The forms that you map to a BaseAction mapping must be a subclass of the
* BaseBean class.  BaseBean continues to simplify the validation and
* reset methods by removing the parameters from the signature as was done with
* the above action method example.
*
* There are 3 ways to map a BeanAction in the struts configuration file.
* They are as follows.
*
* URL Pattern
*
* This approach uses the end of the action definition to determine which
* method to call on the Bean.  For example if you request the URL:
*
* http://localhost/jpetstore4/shop/viewOrder.do
*
* Then the method called would be "viewOrder" (of the mapped bean as specified
* by the name="" parameter in the mapping below).  The mapping used for this
* approach is as follows.
*
*  <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
*    name="orderBean" scope="session"
*    validate="false">
*    <forward name="success" path="/order/ViewOrder.jsp"/>
*  </action>
*  위와 같은 xml문장은 orderBean클래스의 viewOrder메서드를 호출하게 된다.
*
* Method Parameter
*
* This approach uses the Struts action parameter within the mapping
* to determine the method to call on the Bean.  For example the
* following action mapping would cause the "viewOrder" method to
* be called on the bean ("orderBean").  The mapping used for this
* approach is as follows.
*
*  <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
*    name="orderBean" parameter="viewOrder" scope="session"
*    validate="false">
*    <forward name="success" path="/order/ViewOrder.jsp"/>
*  </action>
*
* No Method call
*
* BeanAction will ignore any Struts action mappings without beans associated
* to them (i.e. no name="" attribute in the mapping).  If you do want to associate
* a bean to the action mapping, but do not want a method to be called, simply
* set the parameter to an asterisk ("*").  The mapping used for this approach
* is as follows (no method will be called).
*
*  <action path="/shop/viewOrder" type="com.ibatis.struts.BeanAction"
*    name="orderBean" parameter="*" scope="session"
*    validate="false">
*    <forward name="success" path="/order/ViewOrder.jsp"/>
*  </action>
*
*
* A WORK IN PROGRESS;
*
* <i>The BeanAction Struts extension is a work in progress.  While it demonstrates
* good patterns for application development, the framework itself is very new and
* should not be considered stable.  Your comments and suggestions are welcome.
* Please visit http://www.ibatis.com for contact information.
*
* Date: Mar 11, 2004 10:03:56 PM
*
* @author Clinton Begin
* @see BaseBean
* @see ActionContext
*/
public class BeanAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
      throws Exception {

    String forward = "success";

    try {

      ActionContext.initialize(request, response);

      if (form != null) {

        // Explicit Method Mapping
        Method method = null;
        String methodName = mapping.getParameter();
        if (methodName != null && !"*".equals(methodName)) {
          try {
            method = form.getClass().getMethod(methodName, null);
            forward = (String) method.invoke(form, null);
          } catch (Exception e) {
            throw new BeanActionException("Error dispatching bean action via method parameter ('" + methodName + "').  Cause: " + e, e);
          }
        }

        // Path Based Method Mapping
        if (method == null && !"*".equals(methodName)) {
          methodName = mapping.getPath();
          if (methodName.length() > 1) {
            int slash = methodName.lastIndexOf("/") + 1;
            methodName = methodName.substring(slash);
            if (methodName.length() > 0) {
              try {
                method = form.getClass().getMethod(methodName, null);
                forward = (String) method.invoke(form, null);
              } catch (Exception e) {
                throw new BeanActionException("Error dispatching bean action via URL pattern ('" + methodName + "').  Cause: " + e, e);
              }
            }
          }
        }
      }

    } catch (Exception e) {
      request.setAttribute("BeanActionException", e);
      throw e;
    }

    return mapping.findForward(forward);
  }

}