python的小工具,把hibernate reverse engine生成的java文件转换为scala的

最近需要把hibernate reverse enginering生成的java entity代码转换为scala的(虽然scala能够直接调用java的代码)。Scala的语法虽然和java很相近,但是手工改起来还是很麻烦。

先是考察了antlr,不过由于hibernate生成的文件格式十分工整,用antlr似乎有点牛刀杀鸡的嫌疑。看了python antlr的文档,发现antlr3的语法变得厉害,而且对ast解析的tree parser也很复杂,不像是短时间内能搞定的,于是决定放弃lexer,裸写正则表达式处理,主要牵涉到annotation、构造函数以及函数定义的处理,大约2个多小时完工,这是代码。

python 代码
  1. import os,sys,re  
  2.   
  3. def doFunction(*args):   
  4.     arglist = args[3].split(",")   
  5.     newargs = []   
  6.     for arg in arglist:           
  7.         newargs.appendre.sub("(\S+)\s+(\S+)", r"\2: \1", arg.strip()) )   
  8.     newargstr = ", ".join(newargs)    
  9.     return "%sdef %s(%s) = %s\n" % (args[0], args[2], newargstr, args[4])   
  10.   
  11. def doConstructor(*args):   
  12.     arglist = args[2].split(",")   
  13.     newargs = []   
  14.     for arg in arglist:           
  15.         newargs.appendre.sub("(\S+)\s+(\S+)", r"\2: \1", arg.strip()) )   
  16.     newargstr = ", ".join(newargs)    
  17.     return "%sdef this(%s) = %s\n%sthis();\n" % (args[0], newargstr, args[3], " "*16)   
  18.   
  19. def doAnnotation(*args):   
  20.     arglist = args[2].split(",")   
  21.     newargs = []   
  22.     for arg in arglist:           
  23.         newargs.appendre.sub("(\S+)\s*=\s*(\S+)", r"val \1 = \2", arg.strip()) )   
  24.     newargstr = ", ".join(newargs)    
  25.     return "%s@%s{%s}%s" % (args[0], args[1], newargstr, args[3])   
  26.   
  27. isInDefaultConstructor = False  
  28. def enterDefaultConstructor(*args):   
  29.     global isInDefaultConstructor   
  30.     isInDefaultConstructor = True  
  31.     return ""   
  32.   
  33. def leaveDefaultConstructor(*args):   
  34.     global isInDefaultConstructor   
  35.     if isInDefaultConstructor:   
  36.         isInDefaultConstructor = False  
  37.         return ""   
  38.     else:   
  39.         return "%s}%s" % (args[0], args[1])   
  40.   
  41. funclist = (           
  42.   ("(\s*)public\s+(\S+)\s*\(([^\)]+)\)(.*)", doConstructor),   
  43.   ("(\s*)public\s+(\S+)\s+([^\(;{]+)\s*\(\s*([^\)]+)\s*\)(.*)", doFunction),   
  44.   ("(\s*)public\s+(\S+)\s*\(\s*\)(.*)", enterDefaultConstructor),   
  45.   ("(\s*)}(\s*)", leaveDefaultConstructor),   
  46.   ("(\s*)@(\w+)\(([^\)=]+=[^\)]+)\)([^{]*)", doAnnotation),   
  47. )   
  48.   
  49. relist = (   
  50.   ("import ([^;\*]+)(\*);", r"import \1._"),    
  51.   ("import ([^;\*]+);", r"import \1"),   
  52.   ("(\w+)\s+class\s+(\w+)\s+implements(.*)", r"class \2 extends \3"),   
  53.   ("(\s*)public\s+(\S+)\s+([^;\(]+);", r"var \3: \2 = _"),   
  54.   ("(\s*)private\s+(\S+)\s+([^;\(]+);", r"\1private var \3: \2 = _"),   
  55.   ("(\s*)public\s+(\S+)\s+([^\(;{]+)\s*\(\s*\)(.*)", r"\1def \3() = {"),   
  56.   ("(\s*)return\s+([^;]+);(.*)", r"\1\2"),       
  57. )   
  58.   
  59. def convert(inputfile, outputfile):   
  60.     input = file(inputfile, "r")   
  61.     output = file(outputfile, "w")   
  62.     for eachline in input.readlines():   
  63.         matched = False  
  64.         for reitem in relist:   
  65.             if re.match(reitem[0], eachline):   
  66.                 newline = re.sub(reitem[0], reitem[1], eachline)   
  67.                 matched = True  
  68.                 print newline.rstrip()   
  69.                 output.write(newline)   
  70.                 continue  
  71.         if matched:   
  72.             continue  
  73.                            
  74.         for reitem in funclist:   
  75.             result = re.match(reitem[0], eachline)   
  76.             if result:   
  77.                 newline = reitem[1](*result.groups())   
  78.                 matched = True  
  79.                 print newline   
  80.                 output.write(newline)   
  81.                 continue      
  82.         if matched:   
  83.             continue  
  84.            
  85.         print eachline   
  86.         output.write(eachline)   
  87.   
  88. def getOutputFilename(inputfile):   
  89.     if inputfile.endswith(".java"):   
  90.         return inputfile[:-5] + ".scala"   
  91.     else:   
  92.         return inputfile + ".scala"    
  93.   
  94. if __name__ == "__main__":   
  95.     inputfile = "./src/base/input.java"   
  96.     outputfile = getOutputFilename(inputfile)   
  97.     convert(inputfile, outputfile)   

输入一个java文件

java 代码
  1. package base;   
  2.   
  3. import java.util.Date;   
  4. import javax.persistence.Column;   
  5. import javax.persistence.Entity;   
  6. import javax.persistence.Id;   
  7. import javax.persistence.Table;   
  8. import javax.persistence.Temporal;   
  9. import javax.persistence.TemporalType;   
  10.   
  11. /**  
  12. * VoteVote generated by hbm2java  
  13. */  
  14. @Entity  
  15. @Table(name = "mytable", catalog = "mydb")   
  16. public class MyTable implements java.io.Serializable {   
  17.   
  18.         private int id;   
  19.   
  20.         private String text;   
  21.   
  22.         private Date date;   
  23.   
  24.         private String tags;   
  25.   
  26.         public VoteVote() {   
  27.         }   
  28.   
  29.         public VoteVote(int id, String text, Date date) {   
  30.                 this.id = id;   
  31.                 this.text = text;   
  32.                 this.date = date;   
  33.         }   
  34.   
  35.         public VoteVote(int id, String text, Date date, String tags) {   
  36.                 this.id = id;   
  37.                 this.text = text;   
  38.                 this.date = date;   
  39.                 this.tags = tags;   
  40.         }   
  41.   
  42.         @Id  
  43.         @Column(name = "id", unique = true, nullable = false)   
  44.         public int getId() {   
  45.                 return this.id;   
  46.         }   
  47.   
  48.         public void setId(int id) {   
  49.                 this.id = id;   
  50.         }   
  51.   
  52.         @Column(name = "text", nullable = false)   
  53.         public String getText() {   
  54.                 return this.text;   
  55.         }   
  56.   
  57.         public void setText(String text) {   
  58.                 this.text = text;   
  59.         }   
  60.   
  61.         @Temporal(TemporalType.DATE)   
  62.         @Column(name = "date", nullable = false, length = 0)   
  63.         public Date getDate() {   
  64.                 return this.date;   
  65.         }   
  66.   
  67.         public void setDate(Date date) {   
  68.                 this.date = date;   
  69.         }   
  70.   
  71.         @Column(name = "tags")   
  72.         public String getTags() {   
  73.                 return this.tags;   
  74.         }   
  75.   
  76.         public void setTags(String tags) {   
  77.                 this.tags = tags;   
  78.         }   
  79.   
  80. }   

输出scala代码

scala 代码
  1. package base;   
  2.   
  3. import java.util.Date   
  4. import javax.persistence.Column   
  5. import javax.persistence.Entity   
  6. import javax.persistence.Id   
  7. import javax.persistence.Table   
  8. import javax.persistence.Temporal   
  9. import javax.persistence.TemporalType   
  10.   
  11. /**  
  12. * VoteVote generated by hbm2java  
  13. */  
  14. @Entity  
  15. @Table{val name = "mytable", val catalog = "mydb"}   
  16. class MyTable extends  java.io.Serializable {   
  17.   
  18.         private var id: int = _   
  19.   
  20.         private var text: String = _   
  21.   
  22.         private var date: Date = _   
  23.   
  24.         private var tags: String = _   
  25.   
  26.   
  27.         def this(id: int, text: String, date: Date) =  {   
  28.                 this();   
  29.                 this.id = id;   
  30.                 this.text = text;   
  31.                 this.date = date;   
  32.         }   
  33.   
  34.         def this(id: int, text: String, date: Date, tags: String) =  {   
  35.                 this();   
  36.                 this.id = id;   
  37.                 this.text = text;   
  38.                 this.date = date;   
  39.                 this.tags = tags;   
  40.         }   
  41.   
  42.         @Id  
  43.         @Column{val name = "id", val unique = true, val nullable = false}   
  44.         def getId() = {   
  45.                 this.id   
  46.         }   
  47.   
  48.         def setId(id: int) =  {   
  49.                 this.id = id;   
  50.         }   
  51.   
  52.         @Column{val name = "text", val nullable = false}   
  53.         def getText() = {   
  54.                 this.text   
  55.         }   
  56.   
  57.         def setText(text: String) =  {   
  58.                 this.text = text;   
  59.         }   
  60.   
  61.         @Temporal(TemporalType.DATE)   
  62.         @Column{val name = "date", val nullable = false, val length = 0}   
  63.         def getDate() = {   
  64.                 this.date   
  65.         }   
  66.   
  67.         def setDate(date: Date) =  {   
  68.                 this.date = date;   
  69.         }   
  70.   
  71.         @Column{val name = "tags"}   
  72.         def getTags() = {   
  73.                 this.tags   
  74.         }   
  75.   
  76.         def setTags(tags: String) =  {   
  77.                 this.tags = tags;   
  78.         }   
  79.   
  80. }   

呵呵,完美完成任务

 

你可能感兴趣的:(java,scala,Hibernate,python,正则表达式)