Thanks Ivan!  This looks like very useful code.  I'd definitely like
to have generic Controllers and views for all web frameworks in
AppFuse.  That way, you could add a POJO and have master/detail
screens w/o writing any code.

FWIW... the project I'm currently working on has a similar
FormController.  The said they ended up customizing almost all their
forms and it's no longer used. Interesting, eh?

Matt

On 3/11/07, Ivan Garcia <[EMAIL PROTECTED]> wrote:

With SpringMVC you can create generic based controllers ...

you will need, though, to extend your persistent objects from a common base
class holding the id and a 'isNew' convenience method

this can reduce to almost zero the amount of java code to create
master/detail pages (which use to be a large part of most applications ;-)

Now if springmvc had something like webwork template based tags it could be
the killing web framework :D

Hope it helps

Regards
Ivan


---------------- PersistentObject.java --------------------------------
@MappedSuperclass
public abstract class PersistentObject extends BaseObject {

        protected Long id;
        protected Integer version;

        @Id  @GeneratedValue(strategy=GenerationType.AUTO)
        public Long getId() {
            return id;
        }

        @Version
        public Integer getVersion() {
            return version;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public void setVersion(Integer version) {
            this.version = version;
        }

        @Transient
        public boolean isNew() {
                return getId() == null;
        }

}
----------------------------------------------------------------------


-------------- GenericFormController.java ----------------------

import java.util.Locale;

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

import org.apache.commons.lang.StringUtils;
import org.appfuse.service.GenericManager;
import org.appfuse.tutorial.model.PersistentObject;
import org.appfuse.webapp.controller.BaseFormController;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;

/**
 * GenericFormController
 *
 * <p>
 *  GenericFormController.java.html View Source
 * </p>
 *
 * @author Ivan Garcia Sainz-Aja
 *
 */
public class GenericFormController<T extends PersistentObject> extends
BaseFormController {

    private GenericManager<T,Long> manager = null;

    /**
     * Setter for the field manager
     * @param manager The manager to set.
     */
    public void setManager(GenericManager<T,Long> manager) {
        this.manager = manager;
    }

    /**
     * Persists given perstistentObject using configured GenericManager.
     * @param persistentObject
     * @throws Exception
     */
    protected void doSave(PersistentObject persistentObject) throws
Exception {
        manager.save((T)persistentObject);
    }

    /**
     * Removes the given persistentObject using configured GenericManager.
     * @param persistentObject
     * @throws Exception
     */
    protected void doDelete(PersistentObject persistentObject) throws
Exception {
        manager.remove(persistentObject.getId());
    }

    /**
     * @see
org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse, java.lang.Object,
org.springframework.validation.BindException)
     */
    @Override
    protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors) throws
Exception {
        log.debug("entering 'onSubmit' method...");

        PersistentObject persistentObject = (PersistentObject) command;
        boolean isNew = persistentObject.isNew();
        String success = getSuccessView();
        Locale locale = request.getLocale();

        if (request.getParameter("delete") != null) {
            doDelete(persistentObject);
            success = getViewAfterDelete();
            saveMessage(request, getText(getCommandName() + ".deleted", 
locale));
        }
        else{
            doSave(persistentObject);
            success = (isNew? getViewAfterInsert(): getViewAfterUpdate());
            String key = getCommandName() + ( (isNew) ? ".added" : ".updated");
            saveMessage(request, getText(key, locale));
        }

        return new ModelAndView(success, "id" , persistentObject.getId());
    }

    /**
     * @see
org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
     */
    @Override
    protected Object formBackingObject(HttpServletRequest request) throws
Exception {
        String id = request.getParameter("id");
        if (!StringUtils.isEmpty(id) && StringUtils.isNumeric(id)) {
            return manager.get(new Long(id));
        }

        return createCommand();
    }

    //Configurable success views ...
    private String viewAfterInsert;
    private String viewAfterUpdate;
    private String viewAfterDelete;

    /**
     * Returns the name of the view that should be shown on successful
delete.
     * Defaults to successView in case it is null.
     * @return the viewAfterDelete
     */
    public String getViewAfterDelete() {
        return (viewAfterDelete != null ? viewAfterDelete :
getSuccessView()) ;
    }

    /**
     * Returns the name of the view that should be shown on successful
insert.
     * Defaults to successView in case it is null.
     * @return the viewAfterInsert
     */
    public String getViewAfterInsert() {
        return (viewAfterInsert != null ? viewAfterInsert :
getSuccessView()) ;
    }

    /**
     * Returns the name of the view that should be shown on successful
update.
     * Defaults to successView in case it is null.
     * @return the viewAfterUpdate
     */
    public String getViewAfterUpdate() {
        return (viewAfterUpdate != null ? viewAfterUpdate :
getSuccessView()) ;
    }

    /**
     * @param viewAfterDelete the viewAfterDelete to set
     */
    public void setViewAfterDelete(String viewAfterDelete) {
        this.viewAfterDelete = viewAfterDelete;
    }

    /**
     * @param viewAfterInsert the viewAfterInsert to set
     */
    public void setViewAfterInsert(String viewAfterInsert) {
        this.viewAfterInsert = viewAfterInsert;
    }

    /**
     * @param viewAfterUpdate the viewAfterUpdate to set
     */
    public void setViewAfterUpdate(String viewAfterUpdate) {
        this.viewAfterUpdate = viewAfterUpdate;
    }


}
--------------------------------------------------------------------------


--------------- dispatcher-servlet.xml -------------------------------

    <bean id="personFormController"
class="org.appfuse.tutorial.webapp.controller.GenericFormController">
        <property name="commandName" value="person"/>
        <property name="commandClass" value="org.appfuse.tutorial.model.Person"
/>
        <property name="validator" ref="beanValidator"/>
        <property name="formView" value="personForm"/>
        <property name="successView" value="redirect:persons.html"/>
        <property name="cancelView" value="redirect:mainMenu.html"/>
        <property name="manager" ref="personManager"/>
    </bean>

-------------------------------------------------------------------------


obviously in real life you may need to override some methods (referenceData,
onBind ...) but you already have the bulk of the job done ;-)

--
View this message in context: 
http://www.nabble.com/SpringMVC-can-do-Generic-Controllers-tf3385990s2369.html#a9425059
Sent from the AppFuse - User mailing list archive at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--
http://raibledesigns.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to