/*
 * 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.metaclass;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.grails.commons.metaclass.DynamicConstructor;
import org.codehaus.groovy.grails.exceptions.GrailsDomainException;
import org.codehaus.groovy.grails.web.binding.GrailsDataBinder;
import org.codehaus.groovy.grails.web.metaclass.GrailsParameterMap;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.validation.DataBinder;
import org.springframework.web.bind.ServletRequestDataBinder;
/**
 * A dynamic property that uses a Map of OGNL expressions to sets properties on the target object
 * 
 * @author Graeme Rocher
 * @since 0.3
 * 
 * Created 23/07/06
 */

public class DataBindingDynamicConstructor implements DynamicConstructor {
	private static final Log LOG = LogFactory.getLog( DataBindingDynamicConstructor.class );
	
	public boolean isArgumentsMatch(Object[] args) {
		if(args.length != 1 ) return false;
		if(args[0] == null) return false;
		if(HttpServletRequest.class.isAssignableFrom(args[0].getClass())) return true;
		if(Map.class.isAssignableFrom(args[0].getClass())) return true;
		return false;
	}

	public Object invoke(Class clazz, Object[] args) {
		Object map = args[0];
		Object instance;
		try {
			instance = clazz.newInstance();
		} catch (InstantiationException e1) {
			throw new GrailsDomainException("Error instantiated class [" + clazz + "]: " + e1.getMessage(),e1);
		} catch (IllegalAccessException e1) {
			throw new GrailsDomainException("Illegal access instantiated class [" + clazz + "]: " + e1.getMessage(),e1);
		}
		
		if(map instanceof GrailsParameterMap) {
			GrailsParameterMap parameterMap = (GrailsParameterMap)map;
			HttpServletRequest request = parameterMap.getRequest();
			
			ServletRequestDataBinder dataBinder = GrailsDataBinder.createBinder(map, instance.getClass().getName(),request); 
			dataBinder.bind(request);
			return instance;
		}
		else if (map instanceof HttpServletRequest) {
			HttpServletRequest request = (HttpServletRequest)map;
			ServletRequestDataBinder dataBinder = GrailsDataBinder.createBinder(map, instance.getClass().getName(),request); 
			dataBinder.bind(request);
			return instance;			
		}
		else if(map instanceof Map) {
			
			DataBinder dataBinder = new DataBinder(instance);
			
			PropertyValues pv = new MutablePropertyValues((Map)map);
			dataBinder.bind(pv);
		}
		return instance;
	}

}

@@ -3162,24 +3162,67 @@
 tance);%0D%0A%09%09%09
+Map m = convertPotentialGStrings((Map)map);
 %0D%0A%09%09%09Propert
@@ -3260,24 +3260,17 @@
 yValues(
-(Map)map
+m
 );%0D%0A%09%09%09d
@@ -3313,19 +3313,527 @@
 nstance;%0D%0A%09%7D
+    %0D%0A%09%0D%0A%09private Map convertPotentialGStrings(Map args) %7B  %0D%0A%09%09Map newArgs = new java.util.HashMap();%0D%0A%09%09for(java.util.Iterator i = args.keySet().iterator(); i.hasNext();) %7B%0D%0A%09%09%09Object key = i.next();  %0D%0A%09%09%09Object value = args.get(key);%0D%0A%09%09%09if(key instanceof groovy.lang.GString) %7B%0D%0A%09%09%09%09key = ((groovy.lang.GString)key).toString();%0D%0A%09%09%09%7D%0D%0A%09%09%09if(value instanceof groovy.lang.GString) %7B%0D%0A%09%09%09%09value = ((groovy.lang.GString)value).toString();%09%09%09%09%0D%0A%09%09%09%7D   %0D%0A%09%09%09newArgs.put(key,value);%0D%0A%09%09%7D%0D%0A%09%09return newArgs;%0D%0A%09%7D
 %0D%0A%0D%0A%7D%0D%0A

fix for GRAILS-345