Package juzu.impl.request

Source Code of juzu.impl.request.BeanParameter

/*
* Copyright 2013 eXo Platform SAS
*
* 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 juzu.impl.request;

import juzu.impl.common.AbstractAnnotatedElement;
import juzu.impl.plugin.controller.ControllerService;
import juzu.impl.value.ValueType;
import juzu.request.RequestParameter;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* A bean control parameter.
*
* @author Julien Viet
*/
public class BeanParameter extends ControlParameter {

  public BeanParameter(String name, Class<?> type) throws NullPointerException {
    super(name, type);
  }

  public BeanParameter(String name, AnnotatedElement annotations, Class<?> type) throws NullPointerException {
    super(name, annotations, type);
  }

  <T> T createMappedBean(ControllerService plugin, boolean requiresPrefix, Class<T> clazz, String beanName, Map<String, RequestParameter> parameters) throws IllegalAccessException, InstantiationException {
    // Extract parameters
    Map<String, String[]> beanParams = new HashMap<String, String[]>();
    String prefix = requiresPrefix ? beanName + "." : "";
    for (String key : parameters.keySet()) {
      if (key.startsWith(prefix)) {
        String paramName = key.substring(prefix.length());
        beanParams.put(paramName, parameters.get(key).toArray());
      }
    }

    // Build bean
    T bean = clazz.newInstance();
    for (String key : beanParams.keySet()) {
      String[] value = beanParams.get(key);
      String setterName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1);
      try {
        boolean success = callSetter(plugin, setterName, clazz, bean, value);
        if (!success) {
          Field f = clazz.getField(key);
          Object o = getValue(plugin, f, f.getGenericType(), value);
          if (o != null) {
            f.set(bean, o);
          }
        }
      }
      catch (Exception e) {
        // Do something better
      }

    }
    return bean;
  }

  Object getValue(ControllerService plugin, AnnotatedElement annotated, Type type, String[] value) throws Exception {
    if (type instanceof Class<?>) {
      Class<?> clazz = (Class<?>)type;
      if (clazz.isArray()) {
        clazz = clazz.getComponentType();
        ValueType valueType = plugin.resolveValueType(clazz);
        if (valueType != null) {
          Object array = Array.newInstance(clazz, value.length);
          for (int i = 0;i < value.length;i++) {
            Array.set(array, i, valueType.parse(annotated, value[i]));
          }
          return array;
        }
      } else {
        ValueType valueType = plugin.resolveValueType(clazz);
        if (valueType != null) {
          return valueType.parse(annotated, value[0]);
        }
      }
    } else if (type instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType)type;
      if (List.class.equals(parameterizedType.getRawType())) {
        Type typeArg = parameterizedType.getActualTypeArguments()[0];
        if (typeArg instanceof Class) {
          ValueType valueType = plugin.resolveValueType((Class)typeArg);
          if (valueType != null) {
            ArrayList list = new ArrayList(value.length);
            for (String s : value) {
              list.add(valueType.parse(annotated, s));
            }
            return list;
          }
        }
      }
    }
    return null;
  }

  <T> boolean callSetter(ControllerService plugin, String methodName, Class<T> clazz, T target, String[] value) throws Exception {
    for (final java.lang.reflect.Method m : clazz.getMethods()) {
      if (m.getName().equals(methodName)) {
        int modifiers = m.getModifiers();
        if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
          Type[] parameterTypes = m.getGenericParameterTypes();
          if (parameterTypes.length == 1) {
            AbstractAnnotatedElement element = new AbstractAnnotatedElement() {
              @Override
              public Annotation[] getDeclaredAnnotations() {
                return m.getParameterAnnotations()[0];
              }
            };
            Object o = getValue(plugin, element, parameterTypes[0], value);
            if (o != null) {
              m.invoke(target, o);
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  Map<String, String[]> buildBeanParameter(ControllerService plugin, boolean requiresPrefix, String baseName, Object value) {
    Map<String, String[]> parameters = new HashMap<String, String[]>();

    try {
      for (Field f : value.getClass().getFields()) {
        if (Modifier.isPublic(f.getModifiers())) {
          Object v = f.get(value);
          if (v != null) {
            String name = requiresPrefix ? baseName + "." + f.getName() : f.getName();
            addParameter(plugin, parameters, name, f, f.getGenericType(), v);
          }
        }
      }

      for (java.lang.reflect.Method m : value.getClass().getMethods()) {
        if (Modifier.isPublic(m.getModifiers()) && !Modifier.isStatic(m.getModifiers()) && m.getName().startsWith("get") && m.getName().length() > 3 && m.getParameterTypes().length == 0) {
          Object v = m.invoke(value);
          if (v != null) {
            String n = Character.toLowerCase(m.getName().charAt(3)) + m.getName().substring(4);
            String name = requiresPrefix ? baseName + "." + n : n;
            addParameter(plugin, parameters, name, m, m.getGenericReturnType(), v);
          }
        }
      }
    }
    catch (Exception e) {
    }

    return parameters;
  }

  private void addParameter(ControllerService plugin, Map<String, String[]> parameters, String name, AnnotatedElement annotated, Type type, Object value) {
    String[] v = getParameters(plugin, annotated, type, value);
    if (v != null) {
      parameters.put(name, v);
    }
  }

  private String[] getParameters(ControllerService plugin, AnnotatedElement annotated, Type type, Object value) {
    if (type instanceof Class) {
      Class clazz = (Class)type;
      if (clazz.isArray()) {
        clazz = clazz.getComponentType();
        int length = Array.getLength(value);
        if (length > 0) {
          ValueType valueType = plugin.resolveValueType(clazz);
          if (valueType != null) {
            String[] ret = new String[length];
            for (int i = 0;i < length;i++) {
              Object element = Array.get(value, i);
              ret[i] = valueType.format(annotated, element);
            }
            return ret;
          }
        }
      } else {
        ValueType valueType = plugin.resolveValueType(clazz);
        if (valueType != null) {
          return new String[]{valueType.format(annotated, value)};
        }
      }
    } else if (type instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType)type;
      if (parameterizedType.getRawType().equals(List.class)) {
        List list = (List)value;
        int size = list.size();
        if (size > 0) {
          Type typeArg = parameterizedType.getActualTypeArguments()[0];
          if (typeArg instanceof Class) {
            ValueType valueType = plugin.resolveValueType((Class)typeArg);
            if (valueType != null) {
              String[] ret = new String[size];
              for (int i = 0;i < size;i++) {
                Object element = list.get(i);
                ret[i] = valueType.format(annotated, element);
              }
              return ret;
            }
          }
        }
      }
    }
    return null;
  }
}
TOP

Related Classes of juzu.impl.request.BeanParameter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.