/* * Copyright 2008-2010 the T2 Project ant the Others. * * 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.t2framework.confeito.spi.impl; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Map; import org.t2framework.confeito.Constants; import org.t2framework.confeito.action.ErrorInfo; import org.t2framework.confeito.annotation.Form; import org.t2framework.confeito.contexts.Request; import org.t2framework.confeito.contexts.WebContext; import org.t2framework.confeito.internal.RequestParseUtil; import org.t2framework.confeito.model.Component; import org.t2framework.confeito.model.Property; import org.t2framework.confeito.spi.FormResolver; import org.t2framework.confeito.util.ConverterUtil; import org.t2framework.confeito.util.Logger; import org.t2framework.confeito.util.Reflections.MethodUtil; /** * <#if locale="en"> * <p> * Default implementation of {@code FormResolver}. The constraint of this * implementation is that multiple request parameters converts to List<String>. * </p> * <#else> * <p> * * </p> * </#if> * * @author shot * */ public class FormResolverImpl implements FormResolver { protected static Logger LOG = Logger.getLogger(FormResolverImpl.class); @Override public void resolve(Form form, WebContext context, Component component, ErrorInfo errorInfo) { final Request request = context.getRequest(); Map<String, Map<Integer, Object>> paramMap = RequestParseUtil .createParamMap(request); final String className = component.getName(); for (Property property : component.getProperties()) { final String name = property.propertyName; if (property.writeMethod == null) { LOG.debug(className + "#" + name + " does not have setter method."); continue; } final boolean containsList = paramMap.containsKey(name); if (request.hasMultipleParameters(name) == false && containsList == false) { final Object param = request.getParameter(name); try { Object instance = component.getInstance(); setSingleValue(request, property, instance, param); } catch (Throwable t) { errorInfo.addErrorInfo(className + "#" + name, t); continue; } } else { Object params = null; if (containsList) { Map<Integer, Object> map = paramMap.get(name); params = RequestParseUtil.convertAsList(map); } else { params = request.getParameters(name); } if (params == null) { continue; } try { Object instance = component.getInstance(); setMultipleValues(request, property, instance, params); } catch (Throwable t) { errorInfo.addErrorInfo(className + "#" + name + "[]", t); continue; } } } } protected void setMultipleValues(Request request, Property pd, Object target, Object src) { final Class<?> destType = pd.writeMethod.getParameterTypes()[0]; final Class<? extends Object> srcType = src.getClass(); final Locale locale = request.getLocale(); if (destType.isArray()) { setArrayValue(pd, target, src, destType, srcType, locale); } else if (List.class.isAssignableFrom(destType)) { setListValue(pd, target, src, destType, srcType, locale); } else { MethodUtil.invoke(pd.writeMethod, target, pd.convertArgs(target)); } } @SuppressWarnings("unchecked") protected void setListValue(Property pd, Object target, Object src, Class<? extends Object> destType, Class<? extends Object> srcType, Locale locale) { List<Object> list = null; if (List.class.isAssignableFrom(srcType)) { list = (List<Object>) src; } else if (srcType.isArray()) { list = Arrays.asList((Object[]) src); } Object[] args = Constants.EMPTY_ARRAY; if (list != null) { List<Object> ret = new ArrayList<Object>(); for (Object o : list) { if (o != null && Date.class.isAssignableFrom(o.getClass())) { o = convertToDate(o.toString(), locale); } ret.add(o); } args = pd.convertArgs(ret); } else { args = pd.convertArgs(src); } MethodUtil.invoke(pd.writeMethod, target, args); } @SuppressWarnings("unchecked") protected void setArrayValue(Property pd, Object target, Object src, Class<? extends Object> destType, Class<? extends Object> srcType, Locale locale) { final Class<?> componentType = destType.getComponentType(); Object[] params = null; if (List.class.isAssignableFrom(srcType)) { List<Object> list = (List) src; params = list.toArray(new Object[list.size()]); } else if (srcType.isArray()) { params = (Object[]) src; } if (params != null) { if (Date.class.isAssignableFrom(componentType)) { final int length = params.length; final Date[] dates = new Date[length]; for (int i = 0; i < length; i++) { dates[i] = convertToDate(params[i].toString(), locale); } params = dates; } MethodUtil.invoke(pd.writeMethod, target, pd.convertArgs(params)); } else { MethodUtil.invoke(pd.writeMethod, target, pd.convertArgs(src)); } } protected Date convertToDate(String param, Locale locale) { return ConverterUtil.DATE_CONVERTER.toDate(param, null, locale); } protected void setSingleValue(Request request, Property pd, Object target, Object param) { final Class<?> type = pd.writeMethod.getParameterTypes()[0]; Object value = param; if (Date.class.isAssignableFrom(type)) { final Locale locale = request.getLocale(); value = ConverterUtil.DATE_CONVERTER.toDate(param.toString(), null, locale); } MethodUtil.invoke(pd.writeMethod, target, pd.convertArgs(value)); } }