AikpAction.java :  » Content-Management-System » TransferCM » com » methodhead » aikp » Java Open Source

Java Open Source » Content Management System » TransferCM 
TransferCM » com » methodhead » aikp » AikpAction.java
/* 
 * Copyright (C) 2006 Methodhead Software LLC.  All rights reserved.
 * 
 * This file is part of TransferCM.
 * 
 * TransferCM is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * TransferCM is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * TransferCM; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA  02110-1301  USA
 */

package com.methodhead.aikp;

import java.text.DateFormat;
import java.text.ParseException;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.methodhead.auth.AuthAction;
import com.methodhead.util.StrutsUtil;

import com.methodhead.persistable.PersistableException;
import com.methodhead.MhfException;

import org.apache.log4j.Logger;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

import org.apache.struts.validator.DynaValidatorForm;
import org.apache.struts.action.DynaActionForm;
import org.apache.commons.beanutils.DynaProperty;
import com.methodhead.util.StrutsUtil;
import com.methodhead.util.OperationContext;
import com.methodhead.auth.AuthUser;
import com.methodhead.auth.AuthUtil;
import org.apache.commons.lang.StringUtils;

/**
<p>
  An Struts action with which to build a web interface for {@link
  com.methodhead.aikp.AutoIntKeyPersistable
  AutoIntKeyPersistable}s.  This action will perform the following
  operations: new, edit, save, and delete.  Methods for these operations
  and a number of support methods can be overloaded to achieve more
  sophisticated behaviour.
</p>
<p>
  Using this action requires at least this Struts configuration:
</p>
<xmp>
  <form-bean
    name   ="yourObjectForm"
    dynamic="true"
    type   ="com.methodhead.aikp.AikpForm">

    <form-property name="action"         type="java.lang.String"/>
    <form-property name="id"             type="java.lang.String"/>
    <form-property name="submit"         type="java.lang.String"/>
    <form-property name="cancel"         type="java.lang.String"/>
    <form-property name="delete"         type="java.lang.String"/>
    <form-property name="list"           type="java.util.List"/>

    <!--
      - properties for your object's field...
      -->

  </form-bean>

  <action-mappings>

    <action
      path     ="/yourObject"
      type     ="com.methodhead.aikp.AikpAction"
      parameter="com.your.Policy"
      name     ="yourObjectForm"
      scope    ="request"
      input    ="/yourObject.jsp"
      validate ="true">
      <forward name="list" path="/yourObjectList.jsp"/>
    </action>

  </action-mappings>
</xmp>
<p>
  In addition, the following message resources should be defined:
</p>
<xmp>
  aikpaction.confirm=Delete {0}?
  aikpaction.deleted=Deleted {0}.
  aikpaction.saved=Saved {0}.
</xmp>
<p>
  What operation is performed depends on the <tt>action</tt> parameter
  (and sometimes the <tt>submit</tt> parameter).  A minimal form looks
  like:
</p>
<xmp>
  <%@ page import="com.methodhead.aikp.AikpForm"%>

  <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
  <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>


  <html:errors/>
  <html:form action="/yourObject">
    <html:hidden property="id"/>
    <html:hidden property="action"/>

    <!--
      - inputs for your object...
      -->

    <input type="submit" name="submit" value="Submit"></input> <%

    if ( !form.get( "action" ).equals( "saveNew" ) ) { %>
      <input type="submit" name="submit" value="Delete"></input> <%
    } %>
  </html:form>
</xmp>
<p>
  A minimal list form looks like:
</p>
<xmp>
  <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
  <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
  <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic"%>

  <logic:iterate
    name="yourObjectForm"
    property="list"
    id="yourObject"
    type="com.your.Object">

    <a href="yourObject.do?action=edit&id=<%= yourObject.get( "id" ) %>"><%= yourObject.get( "yourField" ) %></a><br>

  </logic:iterate>
</xmp>
 */
public abstract class AikpAction extends AuthAction {

  // constructors /////////////////////////////////////////////////////////////

  // constants ////////////////////////////////////////////////////////////////

  // classes //////////////////////////////////////////////////////////////////

  // methods //////////////////////////////////////////////////////////////////

  /**
   * Returns a new instance of the persistable to be managed by this action.
   */
  protected abstract AutoIntKeyPersistable createPersistable(
    OperationContext op );

  /**
   * Returns the forward used when the persistable is saved; by default, a
   * forward to input is returned.
   */
  protected ActionForward getForwardForSave(
    OperationContext op,
    Object policy ) {

    return new ActionForward( op.mapping.getInput() );
  }

  /**
   * Returns the forward used when the persistable is deleted; by default, a
   * the <tt>status</tt> forward is returned.
   */
  protected ActionForward getForwardForDelete(
    OperationContext op,
    Object policy ) {

    return op.mapping.findForward( "status" );
  }

  /**
   * Populates the specified form property with the corresponding value from
   * <tt>persistable</tt> using it's <tt>toString()</tt> method (unless it's a
   * date, in which case it is formatted with <tt>DateFormat.getDateInstance(
   * DateFormat.SHORT )</tt>).  
   */
  protected static void populateFormProperty(
    String name,
    DynaActionForm form,
    AutoIntKeyPersistable persistable ) {

    if ( persistable.getDynaClass().getDynaProperty( name ).getType() ==
           Date.class ) {
      DateFormat dateFormat = DateFormat.getDateInstance( DateFormat.SHORT );
      form.set( name, dateFormat.format( persistable.getDate( name ) ) );
    }
    else {
      form.set( name, persistable.get( name ).toString() );
    }
  }

  /**
   * Populates the specified persistable property with the corresponding
   * property from <tt>form</tt>, using {@link
   * com.methodhead.persistable.Persistable#setAsObject
   * Persistable.setAsObject()} to set the value.
   */
  protected static void populatePersistableField(
    String name,
    AutoIntKeyPersistable persistable,
    DynaActionForm form ) {

    persistable.setAsObject( name, form.get( name ) );
  }

  /**
   * Populates the <tt>form</tt> with <tt>persistable</tt>'s field values.  All
   * form fields are expected to be of type <tt>String</tt>.
   */
  protected void populateForm(
    DynaActionForm form,
    AutoIntKeyPersistable persistable ) {

    DynaProperty[] dynaProperties =
      persistable.getDynaClass().getDynaProperties();

    for ( int i = 0; i < dynaProperties.length; i++ ) {
      populateFormProperty( dynaProperties[ i ].getName(), form, persistable );
    }
  }

  /**
   * Populates the <tt>persistable</tt>'s field values with <tt>form</tt>.  All
   * form fields are expected to be of type <tt>String</tt>.  Date fields are
   * parsed using a <tt>DateFormat</tt> as returned by
   * <tt>DateFormat.getDateTimeInstance()</tt>.
   */
  protected void populatePersistable(
    AutoIntKeyPersistable persistable,
    DynaActionForm form ) {

    DynaProperty[] dynaProperties =
      persistable.getDynaClass().getDynaProperties();

    for ( int i = 0; i < dynaProperties.length; i++ ) {
      populatePersistableField(
        dynaProperties[ i ].getName(), persistable, form );
    }
  }

  /**
   * Loads all elements from the database using {@link
   * AutoIntKeyPersistable#loadAll loadAll()} and forwards to <tt>list</tt>.
   */
  protected ActionForward doList(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    op.form.set(
      "list", persistable.loadAll( null, null ) );
    return StrutsUtil.findForward( op.mapping, "list" );
  }

  /**
   * Uses the persistable's default values to initialize the form; a forward to
   * input is returned.
   */
  protected ActionForward doNew(
    OperationContext op,
    Object policy ) {

    populateForm( op.form, createPersistable( op ) );
    op.form.set( "action", "saveNew" );

    return new ActionForward( op.mapping.getInput() );
  }

  /**
   * Loads the persistable using the form's <tt>id</tt> property and uses its
   * field values to initialize the form; a forward to input is returned.
   */
  protected ActionForward doEdit(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );
    populateForm( op.form, persistable );
    op.form.set( "action", "save" );

    return new ActionForward( op.mapping.getInput() );
  }

  /**
   * <p>
   *   Called when an persistable is to be deleted, adds the
   *   <tt>aikpaction.confirm</tt> to the action's messages (accessible by the
   *   Struts <tt>html:messages</tt> tag) and returns a forward to
   *   <tt>confirm</tt>.  <b>Note:</b> The persistable itself is argument 0 to
   *   the message, so make sure its <tt>toString()</tt> method returns
   *   something reasonable if you include <tt>{0}</tt> in your message.  
   * </p>
   */
  protected ActionForward doConfirm(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );

    StrutsUtil.addMessage(
      op.request, "aikpaction.confirm", persistable, null, null );

    op.form.set( "action", "delete" );

    return StrutsUtil.findForward( op.mapping, "confirm" );
  }

  /**
   * Creates the persistable, sets its fields and calls its <tt>saveNew()</tt>
   * method.  The form is then repopulated with values from the saved
   * persistable.  The <tt>aikpaction.saved</tt> message is added to the action
   * and a forward to input is returned.
   */
  protected ActionForward doSaveNew(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    populatePersistable( persistable, op.form );
    persistable.saveNew();
    populateForm( op.form, persistable );
    StrutsUtil.addMessage(
      op.request, "aikpaction.saved", persistable, null, null );
    op.form.set( "action", "save" );

    return getForwardForSave( op, policy );
  }

  /**
   * Loads the persistable using the form's <tt>id</tt> property, sets its
   * fields, and calls its <tt>save()</tt> method.  The form is then
   * repopulated with values from the saved persistable. The
   * <tt>aikpaction.saved</tt> message is added to the action and a forward to
   * input is returned.
   */
  protected ActionForward doSave(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );
    populatePersistable( persistable, op.form );
    persistable.save();
    populateForm( op.form, persistable );
    StrutsUtil.addMessage(
      op.request, "aikpaction.saved", persistable, null, null );
    op.form.set( "action", "save" );

    return getForwardForSave( op, policy );
  }

  /**
   * Like <tt>doEdit()</tt>, <tt>doCancel()</tt> loads the persistable using
   * the form's <tt>id</tt> property, populates the form, adds the
   * <tt>aikpaction.cancelled</tt> message to the action, and returns a forward
   * to input.
   * @deprecated Use {@link #doCancelDelete}
   */
  protected ActionForward doCancel(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );
    populateForm( op.form, persistable );
    op.form.set( "action", "save" );
    StrutsUtil.addMessage(
      op.request, "aikpaction.cancelled", persistable, null, null );

    return new ActionForward( op.mapping.getInput() );
  }

  /**
   * Like <tt>doEdit()</tt>, <tt>doCancelDelete()</tt> loads the persistable using
   * the form's <tt>id</tt> property, populates the form, adds the
   * <tt>aikpaction.cancelled</tt> message to the action, and returns a forward
   * to input.
   */
  protected ActionForward doCancelDelete(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );
    populateForm( op.form, persistable );
    op.form.set( "action", "save" );
    StrutsUtil.addMessage(
      op.request, "aikpaction.cancelled", persistable, null, null );

    return new ActionForward( op.mapping.getInput() );
  }

  /**
   * Like <tt>doEdit()</tt>, <tt>doCancelSave()</tt> loads the persistable using
   * the form's <tt>id</tt> property, populates the form, adds the
   * <tt>aikpaction.cancelled</tt> message to the action, and returns a forward
   * to input.
   */
  protected ActionForward doCancelSave(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );
    populateForm( op.form, persistable );
    op.form.set( "action", "save" );
    StrutsUtil.addMessage(
      op.request, "aikpaction.cancelled", persistable, null, null );

    return new ActionForward( op.mapping.getInput() );
  }

  /**
   * Simply calls <tt>doList()</tt>
   */
  protected ActionForward doCancelSaveNew(
    OperationContext op,
    Object policy ) {

    return doList( op, policy );
  }

  /**
   * <p>
   *   Loads the persistable using the form's <tt>id</tt> property, and invokes
   *   its <tt>delete()</tt> method; a the <tt>status</tt> forward is returned.
   * </p>
   * <p>
   *   The <tt>aikpaction.deleted</tt> message is added to the action's messages
   *   (accessible by the Struts <tt>html:messages</tt> tag).  <b>Note:</b> The
   *   persistable itself is argument 0 to the message, so make sure its
   *   <tt>toString()</tt> method returns something reasonable if you include
   *   <tt>{0}</tt> in your message.  
   * </p>
   */
  protected ActionForward doDelete(
    OperationContext op,
    Object policy ) {

    AutoIntKeyPersistable persistable = createPersistable( op );
    persistable.load( new IntKey( op.form.get( "id" ) ) );
    persistable.delete();

    StrutsUtil.addMessage(
      op.request, "aikpaction.deleted", persistable, null, null );

    return getForwardForDelete( op, policy );
  }

  /**
   * Executes the action, calling the appropriate method (<tt>doNew()</tt>,
   * <tt>doEdit()</tt>, etc.) according to the form's properties.
   */
  public ActionForward doExecute(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response ) {

    DynaValidatorForm dynaForm = ( DynaValidatorForm )form;
    Object policy = StrutsUtil.getPolicy( mapping );
    AuthUser user = AuthUtil.getUser( request );

    OperationContext op =
      new OperationContext( mapping, dynaForm, request, response, user );

    String aikpaction = dynaForm.get( "action" ).toString();

    if ( "list".equals( aikpaction ) ) {
      return doList( op, policy );
    }

    if ( "new".equals( aikpaction ) ) {
      return doNew( op, policy );
    }

    else if ( "edit".equals( aikpaction ) ) {
      return doEdit( op, policy );
    }

    else if ( "saveNew".equals( aikpaction ) ) {
      if ( !StringUtils.isBlank( ( String )dynaForm.get( "cancel" ) ) )
        return doCancelSaveNew( op, policy );
      else
        return doSaveNew( op, policy );
    }

    else if ( "save".equals( aikpaction ) ) {

      if ( !StringUtils.isBlank( ( String )dynaForm.get( "cancel" ) ) )
        return doCancelSave( op, policy );
      else if ( !StringUtils.isBlank( ( String )dynaForm.get( "delete" ) ) )
        return doConfirm( op, policy );
      else
        return doSave( op, policy );
    }

    else if ( "delete".equals( aikpaction ) ) {

      if ( !StringUtils.isBlank( ( String )dynaForm.get( "cancel" ) ) )
        return doCancelDelete( op, policy );
      else
        return doDelete( op, policy );
    }

    else {
      throw new MhfException( "Unexpected aikpaction \"" + aikpaction + "\"" );
    }
  }

  // properties ///////////////////////////////////////////////////////////////

  // attributes ///////////////////////////////////////////////////////////////

  Logger logger_ = Logger.getLogger( AikpAction.class );
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.