package com.net.tcp;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.net.test.TestVO;
/**
*
* StreamObject decode()/encode()方法生成器
*
*/
public class StreamObjectUtils {
public String getDecode(Class<? extends StreamObject> c){
DecodeUtils utils = new DecodeUtils();
return utils.getDecode(c);
}
public String getEncode(Class<? extends StreamObject> c){
EncodeUtils utils = new EncodeUtils();
return utils.getEncode(c);
}
class DecodeUtils{
public String getDecode(Class<? extends StreamObject> c){
Field[] fields = c.getDeclaredFields();
StringBuffer sb = new StringBuffer();
sb.append("\tpublic void decode(DataPack pack){\n");
for(int i = 0; i < fields.length; i++){
sb.append(getFieldLine(fields[i]));
}
sb.append("\t}");
return sb.toString();
}
public String getFieldLine(Field field){
StringBuffer sb = new StringBuffer();
sb.append("\t\t")
.append(field.getName())
.append(" = ")
.append(getRight(field))
.append(";\n");
return sb.toString();
}
private String getRight(Field field){
StringBuffer sb = new StringBuffer();
if(DataType.isNumberByClassName(field.getType().getSimpleName())){
sb.append("((Number)pack.getObject()).")
.append(getNumberFunction(field.getType().getSimpleName()))
.append("()");
}else{
sb.append("(")
.append(DataType.getObjectNameByClassName(field.getType().getSimpleName()))
.append(")")
.append("pack.getObject()");
}
return sb.toString();
}
private String getNumberFunction(String classname){
String func = null;
if(classname.equals("byte") || classname.equals("Byte")){
func = "byteValue";
}else if(classname.equals("short") || classname.equals("Short")){
func = "shortValue";
}else if(classname.equals("int") || classname.equals("Integer")){
func = "intValue";
}else if(classname.equals("long") || classname.equals("Long")){
func = "longValue";
}else if(classname.equals("float") || classname.equals("Float")){
func = "floatValue";
}else{
func = "doubleValue";
}
return func;
}
}
class EncodeUtils{
public String getEncode(Class<? extends StreamObject> c){
Field[] fields = c.getDeclaredFields();
Method[] methods = c.getDeclaredMethods();
StringBuffer sb = new StringBuffer();
sb.append("\tpublic void encode(DataPack pack) {\n");
for(int i = 0; i < fields.length; i++){
sb.append(getFieldLine(fields[i], methods));
}
sb.append("\t}");
return sb.toString();
}
public String getFieldLine(Field field, Method[] methods){
StringBuffer sb = new StringBuffer();
sb.append("\t\t")
.append("pack.putObject(")
.append(field.getName());
List<String> types = this.getTypes(field, methods);
for(int i = 0; i < types.size(); i++){
sb.append(", ").append(types.get(i));
}
sb.append(");\n");
return sb.toString();
}
public List<String> getTypes(Field field, Method[] methods){
List<String> list = new ArrayList<String>();
list.add("DataType." + DataType.getTypeNameByClassName(field.getType().getSimpleName()));
if(field.getType().getSimpleName().endsWith("List")){
Type type = getMethod(methods, getFieldMethodName(field)).getGenericReturnType();
list.addAll(getTypes((ParameterizedType)type));
}
return list;
}
public List<String> getTypes(ParameterizedType type){
List<String> list = new ArrayList<String>();
if(type != null){
Type[] types = ((ParameterizedType)type).getActualTypeArguments();
Class<?> c = null;
Type[] types1 = null;
for(Type t : types){
if(t instanceof ParameterizedType){
types1 = ((ParameterizedType)t).getActualTypeArguments();
if(types1 != null){
if(((ParameterizedType)t).getRawType().toString().endsWith("List")){
list.add("DataType." + DataType.getTypeNameByClassName(((ParameterizedType)t).getRawType().toString()));
list.addAll(getTypes((ParameterizedType)t));
}
}
}else{
c = (Class<?>)t;
list.add("DataType." + DataType.getTypeNameByClassName(c.getSimpleName()));
}
}
}
return list;
}
public String getFieldMethodName(Field field){
String name = field.getName();
String h = name.substring(0, 1).toUpperCase();
String l = name.substring(1, name.length());
return "get" + h + l;
}
public Method getMethod(Method[] methods, String methodName){
for(Method method : methods){
if(method.getName().equals(methodName))
return method;
}
return null;
}
}
public static void main(String args[]){
StreamObjectUtils utils = new StreamObjectUtils();
System.out.println(utils.getDecode(TestVO.class));
System.out.println(utils.getEncode(TestVO.class));
}
}