package greencode.kernel; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.UnknownFormatConversionException; import javax.servlet.ServletException; import javax.servlet.http.Part; import greencode.exception.GreencodeError; import greencode.http.enumeration.RequestMethod; import greencode.jscript.DOMHandle; import greencode.jscript.dom.Element; import greencode.jscript.dom.Window; import greencode.jscript.dom.WindowHandle; import greencode.jscript.dom.elements.InputFileElement; import greencode.jscript.dom.elements.custom.ContainerElement; import greencode.jscript.dom.elements.custom.implementation.ContainerElementImplementation; import greencode.jscript.dom.form.annotation.ConvertDateTime; import greencode.jscript.dom.form.convert.Converter; import greencode.util.ArrayUtils; import greencode.util.ClassUtils; import greencode.util.DateUtils; import greencode.util.GenericReflection; import greencode.util.LogMessage; import greencode.util.StringUtils; final class Form { static void processRequestedForm(GreenContext context) throws IllegalArgumentException, IllegalAccessException, IllegalStateException, IOException, ServletException { String formName = context.request.getParameter("__requestedForm"); if(formName != null) { if(formName.equals("null")) throw new GreencodeError(LogMessage.getMessage("green-0049")); final Class<? extends greencode.jscript.dom.Form> formClass = Cache.forms.get(formName); if(formClass == null) throw new GreencodeError(LogMessage.getMessage("green-0032", formName)); context.requestedForm = context.currentWindow.document.forms(formClass); final boolean METHOD_TYPE_IS_GET = context.getRequest().isMethod(RequestMethod.GET); processElements(context, context.requestedForm, METHOD_TYPE_IS_GET, null, null); } } private static void processElements(final GreenContext context, final ContainerElementImplementation container, final boolean METHOD_TYPE_IS_GET, Map<String, Object> map, Map<Integer, ContainerElement<?>> containersForm) throws IllegalArgumentException, IllegalStateException, IllegalAccessException, IOException, ServletException { Field[] fields = greencode.jscript.dom.$Container.getElementFields(container); for(Field f: fields) { greencode.jscript.dom.form.annotation.ElementValue element = f.getAnnotation(greencode.jscript.dom.form.annotation.ElementValue.class); final String parametro = !element.name().isEmpty() ? element.name() : f.getName(); final Class<?> fieldType = f.getType(); Object valor; if(fieldType.isArray() && ClassUtils.isParent(fieldType.getComponentType(), ContainerElement.class) || ClassUtils.isParent(fieldType, ContainerElement.class)) { Object json = map == null ? context.request.getParameter(parametro) : map.get(parametro); if(json == null) continue; final List<Map<String, Object>> list = json instanceof String ? context.gsonInstance.fromJson(context.request.getParameter(parametro), (new ArrayList<Map<String, Object>>()).getClass()) : (List<Map<String, Object>>) json; if(containersForm == null) { containersForm = greencode.jscript.dom.$Container.getContainers(context.requestedForm); containersForm.clear(); } if(fieldType.isArray()) { Class<? extends ContainerElement<?>> clazz = (Class<? extends ContainerElement<?>>) fieldType.getComponentType(); ContainerElement<?>[] containers = (ContainerElement[]) Array.newInstance(clazz, list.size()); for(int i = -1; ++i < containers.length;) { ContainerElement<?> containerElement = (ContainerElement<?>) GenericReflection.NoThrow.newInstance(clazz, new Class<?>[]{Window.class}, context.currentWindow); containers[i] = containerElement; Map<String, Object> containerMap = list.get(i); Integer uid = Integer.parseInt((String) containerMap.get("__uid")); greencode.jscript.$DOMHandle.setUID(containerElement, uid); containersForm.put(uid, containerElement); processElements(context, containerElement, METHOD_TYPE_IS_GET, containerMap, containersForm); } valor = containers; } else { ContainerElement<?> containerElement = (ContainerElement<?>) GenericReflection.NoThrow.newInstance(fieldType, new Class<?>[]{Window.class}, context.currentWindow); valor = containerElement; Map<String, Object> containerMap = list.get(0); Integer uid = Integer.parseInt((String) containerMap.get("__uid")); greencode.jscript.$DOMHandle.setUID(containerElement, uid); containersForm.put(uid, containerElement); processElements(context, containerElement, METHOD_TYPE_IS_GET, containerMap, containersForm); } f.set(container, valor); } else if(fieldType.equals(Part.class)) { f.set(container, context.getRequest().getPart(parametro)); } else if(fieldType.equals(InputFileElement.class)) { DOMHandle.setVariableValue((Element) f.get(container), "value", context.getRequest().getPart(parametro)); } else { final Type type = f.getGenericType(); final boolean isElementMultipleValue = greencode.jscript.dom.elements.$Element.isValueMultiSelectable(fieldType); if(isElementMultipleValue || fieldType.isArray()) { final String[] valores; if(map == null) { String[] _valores = context.request.getParameterValues(parametro + "[]"); if(_valores == null) { valor = context.request.getParameter(parametro); valores = valor != null ? new String[]{(String) valor} : null; } else valores = _valores; } else { List<Object> list = (List<Object>) map.get(parametro); valores = list == null ? null : list.toArray(new String[list.size()]); } if(valores == null) { if(isElementMultipleValue) DOMHandle.setVariableValue((Element) f.get(container), "value", null); else f.set(container, null); } else { final Class<?> realFieldType = type instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0] : fieldType.getComponentType(); final Object[] values = (Object[]) Array.newInstance(ClassUtils.toWrapperClass(realFieldType), valores.length); try { for(int i = -1; ++i < valores.length;) { Object _value = greencode.kernel.Form.getFieldValue(context, f, realFieldType, valores[i], element); if(_value == null) throw new GreencodeError(LogMessage.getMessage("green-0019", f.getName(), f.getDeclaringClass().getSimpleName())); if(_value instanceof String) { if(element.trim()) _value = ((String) _value).trim(); if(element.removeMultipleSpaces()) _value = StringUtils.removeMultipleSpaces(((String) _value)); if(METHOD_TYPE_IS_GET) _value = StringUtils.toCharset((String) _value, GreenCodeConfig.Server.View.charset); } values[i] = _value; } if(isElementMultipleValue) { DOMHandle.setVariableValue((Element) f.get(container), "value", values); } else { f.set(container, ClassUtils.isPrimitiveType(fieldType.getComponentType()) ? ArrayUtils.wrapperToPrimitive(values) : values); } } catch(UnknownFormatConversionException e) { throw new GreencodeError(LogMessage.getMessage("green-0013", f.getName(), container.getClass().getSimpleName(), "Date", ConvertDateTime.class.getSimpleName())); } } } else { try { Object result = (map == null ? context.request.getParameter(parametro) : map.get(parametro)); final Class<?> realFieldType = type instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0] : f.getType(); if(result == null) { valor = ClassUtils.isPrimitiveType(realFieldType) ? ClassUtils.getDefaultValue(realFieldType) : null; } else { valor = greencode.kernel.Form.getFieldValue(context, f, realFieldType, result.toString(), element); if(valor instanceof String) { if(element.trim()) valor = ((String) valor).trim(); if(element.removeMultipleSpaces()) valor = StringUtils.removeMultipleSpaces(((String) valor)); if(METHOD_TYPE_IS_GET) valor = StringUtils.toCharset((String) valor, GreenCodeConfig.Server.View.charset); } } if(greencode.jscript.dom.elements.$Element.isElementWithValue(fieldType)) { DOMHandle.setVariableValue((Element) f.get(container), "value", valor); } else { f.set(container, valor); } } catch(UnknownFormatConversionException e) { throw new GreencodeError(LogMessage.getMessage("green-0013", f.getName(), container.getClass().getSimpleName(), "Date", ConvertDateTime.class.getSimpleName())); } } } } } static Object getFieldValue(GreenContext context, Field field, Class<?> instanceClass, final String valor, final greencode.jscript.dom.form.annotation.ElementValue elementAnnotation) throws UnknownFormatConversionException { if(valor != null && !valor.isEmpty()) { if(elementAnnotation.converters().length > 0) { Object lastValue = valor; for(Class<? extends Converter> clazz: elementAnnotation.converters()) { Converter c = GenericReflection.NoThrow.newInstance(clazz, new Class<?>[0]); lastValue = c.set(context, instanceClass, lastValue); } return lastValue; } instanceClass = ClassUtils.toWrapperClass(instanceClass); if(String.class.equals(instanceClass)) return valor; if(Integer.class.equals(instanceClass)) return Integer.parseInt(valor); if(Long.class.equals(instanceClass)) return Long.parseLong(valor); if(Double.class.equals(instanceClass)) return Double.parseDouble(valor); if(Float.class.equals(instanceClass)) return Float.parseFloat(valor); if(Boolean.class.equals(instanceClass)) return valor.equals("true") || valor.equals("1"); if(Character.class.equals(instanceClass)) return valor.charAt(0); if(Byte.class.equals(instanceClass)) return Byte.parseByte(valor); if(Short.class.equals(instanceClass)) return Short.parseShort(valor); if(Date.class.equals(instanceClass)) { if(!field.isAnnotationPresent(ConvertDateTime.class)) throw new UnknownFormatConversionException("green-0013"); ConvertDateTime convert = field.getAnnotation(ConvertDateTime.class); try { return DateUtils.toDate(valor, convert.pattern()); } catch(ParseException e) { throw new GreencodeError(LogMessage.getMessage("green-0033", valor, convert.pattern())); } } Object v = WindowHandle.getObjectParamter(context.currentWindow, (String) valor); return v == null ? valor : v; } return null; } }