/*
 * Copyright 2004-2005 the original author or authors.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
package org.codehaus.groovy.grails.scaffolding;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.grails.web.binding.GrailsDataBinder;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.web.bind.ServletRequestDataBinder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * Default implementation of the ScaffoldRequestHandler interface
 * 
 * @author Graeme Rocher
 * @since 30 Nov 2005
 */
public class DefaultScaffoldRequestHandler implements ScaffoldRequestHandler {

    private static final Log LOG = LogFactory.getLog(DefaultScaffoldRequestHandler.class);

    private static final String PARAM_MAX = "max";
    private static final String PARAM_OFFSET = "offset";
    private static final String PARAM_ID = "id";
    private static final String PARAM_SORT = "sort";
    private static final String PARAM_ORDER = "order";

    private ScaffoldDomain domain;

    public void setScaffoldDomain(ScaffoldDomain domain) {
        this.domain = domain;
    }

    public ScaffoldDomain getScaffoldDomain() {
        return this.domain;
    }

    public Map handleList(HttpServletRequest request,
                          HttpServletResponse response) {
        int max = 10;
        int offset = 0;
        String maxParam = request.getParameter(PARAM_MAX);
        String offsetParam = request.getParameter(PARAM_OFFSET);

        if(!StringUtils.isBlank(maxParam)) {
            try {
                max = Integer.parseInt(maxParam);
            }
            catch(NumberFormatException nfe) {
                LOG.warn("[ScaffoldRequestHandler] Error parsing max parameter ["+maxParam+"] for request", nfe);
            }
        }
        if(!StringUtils.isBlank(offsetParam)) {
            try {
                offset = Integer.parseInt(offsetParam);
            }
            catch(NumberFormatException nfe) {
                LOG.warn("[ScaffoldRequestHandler] Error parsing offset parameter ["+offsetParam+"] for request", nfe);
            }
        }
        if(LOG.isTraceEnabled()) {
            LOG.trace("[ScaffoldRequestHandler] Executing [list] for max ["+max+"] and offset ["+offset+"]");
        }
        Map model = new HashMap();
        model.put( domain.getPluralName(), domain.list(max, offset, request.getParameter(PARAM_SORT), request.getParameter(PARAM_ORDER)) );

        if(LOG.isTraceEnabled()) {
            LOG.trace("[ScaffoldRequestHandler] Returned model ["+model+"] from domain method [list]");
        }

        return model;
    }

    public Map handleShow(HttpServletRequest request,
                          HttpServletResponse response, ScaffoldCallback callback) {

        String id = request.getParameter(PARAM_ID);
        if(StringUtils.isBlank(id)) {
            LOG.debug("[ScaffoldRequestHandler] No ID parameter ["+id+"] for request [show]");
            callback.setInvoked(false);
            return Collections.EMPTY_MAP;
        }


        Map model = new HashMap();
        Object domainObject = domain.get(id);
        model.put(domain.getSingularName(), domainObject);
        callback.setInvoked(true);

        return model;
    }

    public Map handleDelete(HttpServletRequest request,
                            HttpServletResponse response, ScaffoldCallback callback) {

        String id = request.getParameter(PARAM_ID);
        if(StringUtils.isBlank(id)) {
            LOG.debug("[ScaffoldRequestHandler] No ID parameter ["+id+"] for request [delete]");
            callback.setInvoked(false);
            return Collections.EMPTY_MAP;
        }


        Map model = new HashMap();
        Object domainObject = domain.get(id);
        model.put(domain.getSingularName(), domainObject);

        if(domainObject != null) {
            domain.delete(id);
            callback.setInvoked(true);
        }

        return model;
    }

    public Map handleCreate(HttpServletRequest request, HttpServletResponse reponse, ScaffoldCallback callback) {
       Object domainObject = domain.newInstance();
        ServletRequestDataBinder dataBinder = GrailsDataBinder.createBinder(domainObject, domain.getName(),request);
        dataBinder.bind(request);

        Map model = new HashMap();
        model.put( domain.getSingularName(), domainObject);

        return model;
    }

    public Map handleSave(HttpServletRequest request,
                          HttpServletResponse reponse, ScaffoldCallback callback) {

        Object domainObject = domain.newInstance();
        ServletRequestDataBinder dataBinder = GrailsDataBinder.createBinder(domainObject, domain.getName(),request);
        dataBinder.bind(request);

        Map model = new HashMap();
        model.put( domain.getSingularName(), domainObject);

        if( this.domain.save(domainObject,callback) ) {
            BeanWrapper domainBean = new BeanWrapperImpl(domainObject);
            Object identity = domainBean.getPropertyValue(domain.getIdentityPropertyName());
            model.put( PARAM_ID, identity );
            callback.setInvoked(true);
        }
        return model;
    }


    public Map handleUpdate(HttpServletRequest request, HttpServletResponse reponse, ScaffoldCallback callback) {
        String id = request.getParameter(PARAM_ID);
        if(StringUtils.isBlank(id)) {
            LOG.debug("[ScaffoldRequestHandler] No ID parameter ["+id+"] for request [update]");
            callback.setInvoked(false);
            return Collections.EMPTY_MAP;
        }

        Object domainObject = this.domain.get(id);
        ServletRequestDataBinder dataBinder = GrailsDataBinder.createBinder(domainObject, domain.getName(),request);
        dataBinder.bind(request);

        Map model = new HashMap();
        model.put(	this.domain.getSingularName(), domainObject);
        model.put( PARAM_ID, id );
        // execute update
        this.domain.update(domainObject,callback);

        return model;
    }

    public Map handleFind(HttpServletRequest request,
                          HttpServletResponse reponse) {
        // TODO Auto-generated method stub
        return null;
    }

}

@@ -6720,32 +6720,35 @@
  update%0A        
+if(
 this.domain.upda
@@ -6772,16 +6772,52 @@
 allback)
+)%0A        %09callback.setInvoked(true)
 ;%0A%0A     

fix for GRAILS-404