Skip to content

Instantly share code, notes, and snippets.

@yongchun
Created January 8, 2014 02:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yongchun/8310436 to your computer and use it in GitHub Desktop.
Save yongchun/8310436 to your computer and use it in GitHub Desktop.
自动化测试原型
package com.snda.sysdev.util;
import com.snda.sysdev.template.bean.InterfaceFuncParam;
import org.springframework.beans.BeanUtils;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 对于一个JavaBean其属性类型可能有一下几种 <br/>
* 1.原生类型及其包装类/String<br/>
* 2.包装类的集合如List<Integer>/数组/List<String>/String[]<br/>
* 3.JavaBean的集合类型如List<JavaBean><br/>
* 4.JavaBean类型<br/>
* 5.Map<String,Object>类型<br/>
* 6.JavaBean的数组类型JavaBean[] 这些都可能递归出现
* */
public class ClassProperty2KeyUtil {
public static void getKey(Class<?> parameterType,
InterfaceFuncParam keyDesc, List<InterfaceFuncParam> kds) {
PropertyDescriptor[] pds = BeanUtils
.getPropertyDescriptors(parameterType); // @RequestBody 对应的参数
for (PropertyDescriptor pd : pds) {
if ("class".equals(pd.getName())) { // TODO
continue;
}
String propertyName = pd.getName(); // 属性名称
Method propertyWriter = pd.getWriteMethod(); // 获取属性的写方法
Type[] paramTypes = null;
if (propertyWriter != null) {
paramTypes = propertyWriter.getGenericParameterTypes();
}
if (paramTypes == null || paramTypes.length != 1) {
continue;
}
Integer type = getTypeCategory(paramTypes[0]);
InterfaceFuncParam param = new InterfaceFuncParam(propertyName,
Boolean.FALSE, getTypeName(paramTypes[0]), type);
;
if (TypeCategory.TC_SIMPLE.getValue() == type // 1.原生类型及其包装类(包括String及其Void)
|| TypeCategory.TC_SIMPLE_COLLECTION.getValue() == type) { // 2.原生类型及其包装类(包括String及其Void)的数组和集合
Class<?> propertyType = null;
if (paramTypes[0] instanceof Class) {
propertyType = (Class<?>) paramTypes[0];
} else {
propertyType = ((ParameterizedTypeImpl) paramTypes[0])
.getRawType();// 对集合类的处理
}
param = new InterfaceFuncParam(propertyName, Boolean.FALSE,
getTypeName(paramTypes[0]), type);
getPropertyKey(propertyType, param, kds, type);
} else if (TypeCategory.TC_COMPLEX.getValue() == type) { // 3.JavaBean的集合
StringBuilder sb = new StringBuilder();
ParameterizedType pt = (ParameterizedType) paramTypes[0];
Type elemType = null;
if (Collection.class.isAssignableFrom((Class<?>) pt
.getRawType())) { // pt.getRawType()返回表示声明此类型的类或接口
elemType = pt.getActualTypeArguments()[0];
}
Class<?> propertyType = (Class<?>) elemType;
getPropertyKey(propertyType, param, kds, type);
getJsonStringProxy(param, sb);
param.setJsonString(sb.toString());
} else if (TypeCategory.TC_BEAN.getValue() == type) { // 4.JavaBean
StringBuilder sb = new StringBuilder();
Class<?> propertyType = (Class<?>) paramTypes[0];
getPropertyKey(propertyType, param, kds, type);
getJsonStringProxy(param, sb);
param.setJsonString(sb.toString());
} else if (TypeCategory.TC_MAP.getValue() == type) {// 5.Map类型
StringBuilder sb = new StringBuilder();
getPropertyKey(Map.class, param, kds, type);
getJsonStringProxy(param, sb);
param.setJsonString(sb.toString());
} else if (TypeCategory.TC_BEAN_ARRAY.getValue() == type) {// 6.JavaBean类型的数组
Class<?> propertyType = (Class<?>) paramTypes[0];
Class<?> elemClass = propertyType.getComponentType();// 获取数组的类型
StringBuilder sb = new StringBuilder();
getPropertyKey(elemClass, param, kds, type);
getJsonStringProxy(param, sb);
param.setJsonString(sb.toString());
}
addKeyDesc(keyDesc, param, kds);
}
}
/**
* 该方法是判断将target添加到kds里还是添加到source.children里
* */
private static void addKeyDesc(InterfaceFuncParam source,
InterfaceFuncParam target, List<InterfaceFuncParam> kds) {
StringBuilder jsonSting = null;
if (source == null) {
kds.add(target);
} else {
if (source.getChildren() == null) {
source.setChildren(new ArrayList<InterfaceFuncParam>());
source.getChildren().add(target);
} else {
source.getChildren().add(target);
}
}
}
/**
* 获取属性相应的key
* */
private static void getPropertyKey(Class<?> parameterType,
InterfaceFuncParam keyDesc, List<InterfaceFuncParam> kds,
Integer type) {
keyDesc.setTypeCategory(type);
if (TypeCategory.TC_COMPLEX.getValue() == type) {
getKey(parameterType, keyDesc, kds);
} else if (TypeCategory.TC_BEAN.getValue() == type) {
getKey(parameterType, keyDesc, kds);
} else if (TypeCategory.TC_BEAN_ARRAY.getValue() == type) {
getKey(parameterType, keyDesc, kds);
}
}
public static int getTypeCategory(Type type) {
if (type instanceof Class) {
Class<?> clazz = (Class<?>) type;
if (isSimpleClass(clazz)) {// 1.原生类型及其包装类(包括String及其Void)
return TypeCategory.TC_SIMPLE.getValue();
}
Class<?> elemClass = clazz.getComponentType();// 获取数组的类型
if ((elemClass != null) && isSimpleClass(elemClass)) {// 2.原生类型及其包装类(包括String及其Void)的数组
return TypeCategory.TC_SIMPLE_COLLECTION.getValue();
}
if ((elemClass != null) && !isSimpleClass(elemClass)) {// 6.JavaBean类型的数组
return TypeCategory.TC_BEAN_ARRAY.getValue();
}
return TypeCategory.TC_BEAN.getValue();// 4.JavaBean
}
Type elemType = null;
if (type instanceof GenericArrayType) {
elemType = ((GenericArrayType) type).getGenericComponentType();
} else if (type instanceof ParameterizedType) { // 参数化类型
// 如Collection<String>
ParameterizedType pt = (ParameterizedType) type;
if (Collection.class.isAssignableFrom((Class<?>) pt.getRawType())) { // pt.getRawType()返回表示声明此类型的类或接口
elemType = pt.getActualTypeArguments()[0];
}
if (Map.class.isAssignableFrom((Class<?>) pt.getRawType())) {// 5.Map类型
return TypeCategory.TC_MAP.getValue();
}
}
if (elemType != null) {
if (elemType instanceof Class && isSimpleClass((Class<?>) elemType)) {// 2.原生类型及其包装类(包括String及其Void)的集合
return TypeCategory.TC_SIMPLE_COLLECTION.getValue();
}
if (elemType instanceof WildcardType) {
WildcardType wt = (WildcardType) elemType;
// upperBounds never get zero length
Type[] upperBounds = wt.getUpperBounds();
Type[] lowerBounds = wt.getLowerBounds();
if ((upperBounds.length == 1)
&& (upperBounds[0] == Object.class)
&& (lowerBounds.length == 1)
&& lowerBounds[0] instanceof Class
&& isSimpleClass((Class<?>) lowerBounds[0])) {
return TypeCategory.TC_SIMPLE_COLLECTION.getValue();
}
}
}
return TypeCategory.TC_COMPLEX.getValue(); // 3.JavaBean的集合
}
public static boolean isSimpleClass(Class<?> clazz) {
return (clazz.isPrimitive() || (clazz == Boolean.class)
|| (clazz == Character.class) || (clazz == Byte.class)
|| (clazz == Short.class) || (clazz == Integer.class)
|| (clazz == Long.class) || (clazz == Float.class)
|| (clazz == Double.class) || (clazz == Void.class) || (clazz == String.class));
}
public static String getTypeName(Type type) {
if (type instanceof Class) {
return ((Class<?>) type).getSimpleName();
}
int i;
StringBuilder sb = new StringBuilder();
if (type instanceof GenericArrayType) {
sb.append(getTypeName(((GenericArrayType) type)
.getGenericComponentType()));
sb.append("[]");
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
sb.append(((Class<?>) pt.getRawType()).getSimpleName());
Type[] typeArguments = pt.getActualTypeArguments();
if (typeArguments.length > 0) {
sb.append('<');
for (i = 0; i < typeArguments.length; ++i) {
sb.append(getTypeName(typeArguments[i]));
sb.append(", ");
}
sb.setLength(sb.length() - 2); // delete last ", "
sb.append('>');
}
} else if (type instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) type;
sb.append(tv.getName());
Type[] bounds = tv.getBounds();
if ((bounds.length > 1) || (bounds[0] != Object.class)) {
sb.append(" extends ");
for (i = 0; i < bounds.length; ++i) {
sb.append(getTypeName(bounds[i]));
sb.append(" & ");
}
sb.setLength(sb.length() - 3); // delete last " & "
}
} else if (type instanceof WildcardType) {
sb.append('?');
WildcardType wt = (WildcardType) type;
Type[] upperBounds = wt.getUpperBounds();
if ((upperBounds.length > 1) || (upperBounds[0] != Object.class)) {
sb.append(" extends ");
for (i = 0; i < upperBounds.length; ++i) {
sb.append(getTypeName(upperBounds[i]));
sb.append(" & ");
}
sb.setLength(sb.length() - 3); // delete last " & "
}
Type[] lowerBounds = wt.getLowerBounds();
if (lowerBounds.length > 0) {
sb.append(" super ");
for (i = 0; i < lowerBounds.length; ++i) {
sb.append(getTypeName(lowerBounds[i]));
sb.append(" & ");
}
sb.setLength(sb.length() - 3); // delete last " & "
}
}
return sb.toString();
}
public static void getJsonStringProxy(InterfaceFuncParam keyDesc,
StringBuilder sb) {
if (TypeCategory.TC_SIMPLE_COLLECTION.getValue() == keyDesc
.getTypeCategory()) { // 数组
getSimpleCollectionJsonString(keyDesc, sb);
}
if (TypeCategory.TC_BEAN_ARRAY.getValue() == keyDesc.getTypeCategory()) {
getBeanArrayJsonString(keyDesc, sb);
}
if (TypeCategory.TC_MAP.getValue() == keyDesc.getTypeCategory()) { // Map
getMapJsonString(keyDesc, sb);
}
if (TypeCategory.TC_BEAN.getValue() == keyDesc.getTypeCategory()) { // JavaBean
getBeanJsonString(keyDesc, sb);
}
if (TypeCategory.TC_COMPLEX.getValue() == keyDesc.getTypeCategory()) { // List<JavaBean>
getComplexJsonString(keyDesc, sb);
}
}
private static void getSimpleJsonString(InterfaceFuncParam keyDesc,
StringBuilder sb) {
sb.append("\"").append(keyDesc.getName()).append("\"");
sb.append(":");
sb.append("\"\"");
}
private static void getSimpleCollectionJsonString(
InterfaceFuncParam keyDesc, StringBuilder sb) {
sb.append("\"").append(keyDesc.getName()).append("\":").append("[]");
}
private static void getComplexJsonString(InterfaceFuncParam keyDesc,
StringBuilder sb) {
sb.append("\"").append(keyDesc.getName()).append("\":").append("[{");
int i = 0;
int size = keyDesc.getChildren().size();
for (InterfaceFuncParam kd : keyDesc.getChildren()) {
++i;
if (TypeCategory.TC_SIMPLE.getValue() == kd.getTypeCategory()) {
getSimpleJsonString(kd, sb);
} else {
getJsonStringProxy(kd, sb);
}
if (i < size) {
sb.append(",");
}
}
sb.append("}]");
}
private static void getBeanJsonString(InterfaceFuncParam keyDesc,
StringBuilder sb) {
sb.append("\"").append(keyDesc.getName()).append("\":").append("{");
int i = 0;
int size = keyDesc.getChildren().size();
for (InterfaceFuncParam kd : keyDesc.getChildren()) {
++i;
if (TypeCategory.TC_SIMPLE.getValue() == kd.getTypeCategory()) {
getSimpleJsonString(kd, sb);
} else {
getJsonStringProxy(kd, sb);
}
if (i < size) {
sb.append(",");
}
}
sb.append("}");
}
private static void getMapJsonString(InterfaceFuncParam keyDesc,
StringBuilder sb) {
sb.append("\"").append(keyDesc.getName()).append("\":").append("{}");
}
private static void getBeanArrayJsonString(InterfaceFuncParam keyDesc,
StringBuilder sb) {
sb.append("\"").append(keyDesc.getName()).append("\":").append("[{");
int i = 0;
int size = keyDesc.getChildren().size();
for (InterfaceFuncParam kd : keyDesc.getChildren()) {
++i;
if (TypeCategory.TC_SIMPLE.getValue() == kd.getTypeCategory()) {
getSimpleJsonString(kd, sb);
} else {
getJsonStringProxy(kd, sb);
}
if (i < size) {
sb.append(",");
}
}
sb.append("}]");
}
}
package com.snda.sysdev.template.bean;
import java.util.List;
public class InterfaceFuncParam {
private String name;
private Boolean required;
private String typeName;
private int typeCategory;
private List<InterfaceFuncParam> children;
private String jsonString;
public InterfaceFuncParam(String name, Boolean required, String typeName,
Integer typeCategory) {
this.name = name;
this.required = required;
this.typeName = typeName;
this.typeCategory = typeCategory;
}
public String getName() {
return name;
}
public Boolean getRequired() {
return required;
}
public String getTypeName() {
return typeName;
}
public int getTypeCategory() {
return typeCategory;
}
public void setName(String name) {
this.name = name;
}
public void setRequired(Boolean required) {
this.required = required;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public void setTypeCategory(int typeCategory) {
this.typeCategory = typeCategory;
}
public List<InterfaceFuncParam> getChildren() {
return children;
}
public void setChildren(List<InterfaceFuncParam> children) {
this.children = children;
}
public String getJsonString() {
return jsonString;
}
public void setJsonString(String jsonString) {
this.jsonString = jsonString;
}
}
package com.snda.sysdev.util;
/**
* Created with IntelliJ IDEA. User: chengyongchun Date: 14-1-2 Time: 下午6:13 To
* change this template use File | Settings | File Templates.
*/
public enum TypeCategory {
TC_SIMPLE(1), TC_SIMPLE_COLLECTION(2), TC_COMPLEX(3), TC_BEAN(4),TC_MAP(5),TC_BEAN_ARRAY(6);
private Integer value;
private TypeCategory(Integer value) {
this.value = value;
}
public Integer getValue() {
return this.value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment