java flash tcp字節流通信(三)-java StreamObject as3 生成器

package com.net.tcp;

import java.io.File;
import java.io.FileOutputStream;
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.Collection;
import java.util.List;

/**
 *
 * @author 鄭創坤
 * actionscript 3 StreamObject生成器
 *
 */
public class AS3Utils {
 /**生成路徑*/
 private String asClassPath = "as/com/net/test/";
 /**生成包*/
 private String asPack = "com.net.test";
 private String imports[] = {
   "import com.net.tcp.DataPack;",
   "import com.net.tcp.DataType;",
   "import com.net.tcp.StreamObject;",
   "import com.commons.utils.Map;"
   };
 private String head = "public class {0} implements StreamObject";
 private String var = "public var {0}:{1};";
 private String suffix = ".as";
 
 public AS3Utils(){
 }
 
 public void init(String asClassPath, String asPack){
  this.asClassPath = asClassPath;
  if(asPack != null){
   this.asPack = asPack;
  }
 }
 
 public void execute(Collection<Class<?>> classes) throws Exception{
  File file = new File(asClassPath);
  if(!file.exists()){
   file.mkdirs();
  }
  if(file.exists()){
   for(Class<?> c : classes){
    File cf = new File(asClassPath + c.getSimpleName() + suffix);
    if(cf.exists()){
     cf.createNewFile();
    }
    FileOutputStream fos = new FileOutputStream(cf);
    try{
     fos.write(getASClass(c).getBytes("UTF-8"));
     fos.flush();
    }finally{
     fos.close();
    }
   }
  }
 }
 
 public String getASClass(Class<?> c){
  StringBuffer sb = new StringBuffer();
  int tab = 0;
  sb.append(getLine("package " + asPack, tab));
  sb.append(getLine("{", tab++));
  for(String imp : imports){
   sb.append(getLine(imp, tab));
  }
  sb.append(getLine(head.replace("{0}", c.getSimpleName()), tab));
  sb.append(getLine("{", tab++));
  Field[] fields = c.getDeclaredFields();
  for(Field field : fields){
   sb.append(getLine(getVar(field), tab));
  }
  sb.append(getLine(getDecode(c, tab), 0));
  sb.append(getLine(getEncode(c, tab), 0));
  sb.append(getLine("}", --tab));
  sb.append(getLine("}", --tab));
  return sb.toString();
 }
 
 public String getVar(Field f){
  String s = var.replace("{0}", f.getName());
  String classname = ((Class)f.getType()).getSimpleName();
  if(DataType.isNumberByClassName(classname)){
   s = s.replace("{1}", "Number");
  }else if(classname.endsWith("List")){
   s = s.replace("{1}", "Array");
  }else{
   s = s.replace("{1}", DataType.getObjectNameByClassName(classname));
  }
  return s;
 }
 
 public static String getLine(String line, int tabN){
  StringBuffer sb = new StringBuffer();
  for(int i = 0; i < tabN; i++){
   sb.append("\t");
  }
  sb.append(line).append("\n");
  return sb.toString();
 }
 
 public String getDecode(Class<?> c, int tab){
  DecodeUtils utils = new DecodeUtils();
  return utils.getDecode(c, tab);
 }
 
 public String getEncode(Class<?> c, int tab){
  EncodeUtils utils = new EncodeUtils();
  return utils.getEncode(c, tab);
 }
 
 class DecodeUtils{
  private String head = "public function decode(pack:DataPack):void{";
  public String getDecode(Class<?> c, int tab){
   Field[] fields = c.getDeclaredFields();
   StringBuffer sb = new StringBuffer();
   sb.append(AS3Utils.getLine(head, tab++));
   for(int i = 0; i < fields.length; i++){
    sb.append(AS3Utils.getLine(getFieldLine(fields[i]), tab));
   }
   sb.append(AS3Utils.getLine("}", --tab));
   return sb.toString();
  }
  public String getFieldLine(Field field){
   StringBuffer sb = new StringBuffer();
   sb.append(field.getName())
   .append(" = ")
   .append(getRight(field))
   .append(";");
   return sb.toString();
  }
  private String getRight(Field field){
   StringBuffer sb = new StringBuffer();
   if(DataType.isNumberByClassName(field.getType().getSimpleName())){
    sb.append("Number(pack.readObject())");
   }else if(field.getType().getSimpleName().endsWith("List")){
    sb.append("pack.readObject()")
    .append(" as ")
    .append(" Array ");
   }else{
    sb.append("pack.readObject()")
    .append(" as ")
    .append(DataType.getObjectNameByClassName(field.getType().getSimpleName()));
    
   }
   return sb.toString();
  }
 }
 
 class EncodeUtils{
  private String head = "public function encode(pack:DataPack):void{";
  public String getEncode(Class<?> c, int tab){
   Field[] fields = c.getDeclaredFields();
   Method[] methods = c.getDeclaredMethods();
   StringBuffer sb = new StringBuffer();
   sb.append(AS3Utils.getLine(head, tab++));
   for(int i = 0; i < fields.length; i++){
    sb.append(AS3Utils.getLine(getFieldLine(fields[i], methods), tab));
   }
   sb.append(AS3Utils.getLine("}", --tab));
   return sb.toString();
  }
  public String getFieldLine(Field field, Method[] methods){
   StringBuffer sb = new StringBuffer();
   sb.append("pack.writeObject(")
   .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(");");
   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[]) throws Exception{
  StreamObjectManager.init("com.net.test.*");
  AS3Utils utils = new AS3Utils();
  utils.execute(StreamObjectManager.getClasses().values());
 }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章