Last active
August 29, 2015 14:02
-
-
Save pcqpcq/93675e3e02d8d44d8da3 to your computer and use it in GitHub Desktop.
Android JavaBean Generator for android. Java Bean with Parcelable. Version 1.0.1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 使命行参数格式: | |
## ARGV[0] ==> config文件路径[必须有] | |
## ARGV[1] ==> 保存文件路径[必须有] | |
## ARGV[2] ==> 包名[必须有] | |
## | |
## 示例: | |
## ruby ./AndroidBeanGen.rb ./config.txt ./resp com.a.b | |
## | |
## | |
## | |
## | |
## | |
## config文件格式: | |
## Cls:类名1:类注释1 | |
## 属性名1:属性类型1 | |
## Cls:类名2:类注释2 | |
## 属性名2:属性类型2 | |
## | |
## 示例: | |
## Cls:ArticleReqEntity:文章请求实体 | |
## id:int | |
## Cls:ArticleRespEntity:文章响应实体 | |
## id:int | |
## title:String | |
## | |
## | |
## | |
## ps. 目前已知最低兼容ruby1.8.7 | |
## | |
## 1.0.1(2014.03.24):增加set方法集 | |
## 1.0.0(2014.03.20):第一版 | |
## | |
## | |
## | |
# 一个类包含:类名,属性列表和内部类指针 | |
class Clazz | |
def initialize(cls_name) | |
@cls_name = cls_name | |
@cls_comment = "" | |
@attrs=[] | |
@lead_cls_names=nil #前面有几个前导类名 | |
@cls_import_advanced = 0 #是否需要导入额外内容 | |
end | |
def cls_name | |
@cls_name | |
end | |
attr_accessor :cls_comment, :attrs, :lead_cls_names, :cls_import_advanced | |
end | |
#属性 | |
class Attr | |
def initialize(type=nil,name=nil) | |
@type,@name=type,name | |
end | |
attr_accessor :type, :name | |
end | |
class Env | |
def initialize() | |
@clz_list = [] #类的容器 | |
@cur_clz = nil #当前类 | |
@cur_clz_comment = nil #当前类注释 | |
@attr = nil #当前属性 | |
@attr_index=0 #当前类的第几个属性 | |
@clz_index=0 #当前属于第几个类 | |
end | |
attr_accessor :clz_list,:cur_clz,:cur_clz_comment,:attr,:attr_index,:clz_index | |
end | |
$env = Env.new | |
# 转换首字母大写,此处算法为了兼容ruby1.8.7 | |
def getFirstUpcase(str) | |
str_first_cap = str[0].capitalize | |
str_remainder = str[1..str.size-1] | |
str = "#{str_first_cap}#{str_remainder}" | |
return str | |
end | |
# 转换首字母小写,此处算法为了兼容ruby1.8.7 | |
def getFirstDowncase(str) | |
str_first_min = "0#{str}".capitalize[1] | |
str_remainder = str[1..str.size-1] | |
str = "#{str_first_min}#{str_remainder}" | |
return str | |
end | |
def print_clz_list #测试容器数据 | |
$env.clz_list.each do |clzz| | |
lead_cls_names = clzz.lead_cls_names | |
print "============" | |
lead_cls_names.each do |lead_names| | |
print lead_names + "-" | |
end | |
print "#{clzz.cls_name}============\n" | |
attrs = clzz.attrs | |
attrs.each do |attr| | |
puts attr.type + "=" + attr.name | |
end | |
end | |
end | |
def print_cls_import(i) | |
template = "package #{ARGV[2]};\n" | |
template += "\n" | |
template += "import android.os.Parcel;\n" | |
template += "import android.os.Parcelable;\n" | |
template += "import com.google.gson.annotations.SerializedName;\n" | |
if (i == 1) | |
template += "import java.util.List;\n" | |
end | |
template += "\n" | |
template | |
end | |
def print_cls_head(i) | |
clazz = $env.clz_list[i] | |
lead_clz_names = clazz.lead_cls_names | |
lead_num = lead_clz_names.size | |
cls_name = clazz.cls_name | |
cls_comment = clazz.cls_comment | |
template = "/**\n" | |
template += " * #{cls_comment}\n" | |
template += " * <p>build by AndroidBeanGen</p>\n" | |
template += " * <a href=\"https\://gist.github.com/pcqpcq/93675e3e02d8d44d8da3\">get it here</a>\n" | |
template += " */\n" | |
template += "public class #{cls_name} implements Parcelable {\n" | |
# if(i == 0) | |
# template += "public class #{cls_name} {\n" | |
# else | |
# template += "\n" | |
# template += "\t" * lead_num | |
# template += "public static class #{cls_name} {\n" | |
# end | |
template | |
end | |
#返回前导类的个数 | |
def get_lead_num(i) | |
lead_cls_names = $env.clz_list[i].lead_cls_names | |
lead_num = 0 | |
# if(lead_cls_names == nil) | |
# lead_num = 0 | |
# else | |
# lead_num = lead_cls_names.size | |
# end | |
lead_num | |
end | |
def print_cls_end(i) | |
lead_num = get_lead_num(i) | |
template = "\t" * lead_num + "}\n\n" | |
template | |
end | |
def print_attrs(i) | |
lead_type = "\t" * get_lead_num(i) + "\t" | |
attrs = $env.clz_list[i].attrs | |
template = "\n" | |
attrs.each do |attr| | |
type = attr.type | |
name = attr.name | |
template += "#{lead_type}@SerializedName(\"#{name}\")\n" | |
if type == "String" | |
template += "#{lead_type}#{type} #{name} = \"\";\n" | |
else | |
template += "#{lead_type}#{type} #{name};\n" | |
end | |
end | |
template | |
end | |
def get_template(i) | |
clazz = $env.clz_list[i] | |
lead_type = "\t" * get_lead_num(i) + "\t" | |
template = "\n" | |
clazz.attrs.each do |attr| | |
first_cap_name = getFirstUpcase(attr.name) | |
template += "#{lead_type}public #{attr.type} get#{first_cap_name}() {\n" | |
template += "#{lead_type}\treturn #{attr.name};\n" | |
template += "#{lead_type}}\n\n" | |
end | |
template | |
end | |
def set_template(i) | |
clazz = $env.clz_list[i] | |
lead_type = "\t" * get_lead_num(i) + "\t" | |
template = "" | |
clazz.attrs.each do |attr| | |
first_cap_name = getFirstUpcase(attr.name) | |
template += "#{lead_type}public void set#{first_cap_name}(#{attr.type} #{attr.name}) {\n" | |
template += "#{lead_type}\tthis.#{attr.name} = #{attr.name};\n" | |
template += "#{lead_type}}\n\n" | |
end | |
template | |
end | |
def parcel_template(i) | |
clazz = $env.clz_list[i] | |
template = "" | |
# 输出describeContents()方法 | |
template += "\t@Override\n" | |
template += "\tpublic int describeContents() {\n" | |
template += "\t\treturn 0;\n" | |
template += "\t}\n\n" | |
# 输出writeToParcel()方法 | |
template += "\t@Override\n" | |
template += "\tpublic void writeToParcel(Parcel dest, int flags) {\n" | |
clazz.attrs.each do |attr| | |
first_type_name = getFirstUpcase(attr.type) | |
# 特殊处理List | |
if first_type_name.include? "List" | |
first_type_name = "List" | |
end | |
# 特殊处理实体对象 | |
if first_type_name.include? "Entity" | |
first_type_name = "Parcelable" | |
template += "\t\tdest.write#{first_type_name}(this.#{attr.name}, flags);\n" | |
else | |
template += "\t\tdest.write#{first_type_name}(this.#{attr.name});\n" | |
end | |
end | |
template += "\t}\n\n" | |
# 输出CREATOR对象 | |
template += "\tpublic static final Parcelable.Creator<#{clazz.cls_name}> CREATOR = new Creator<#{clazz.cls_name}>() {\n\n" | |
template += "\t\t@Override\n" | |
template += "\t\tpublic #{clazz.cls_name}[] newArray(int size) {\n" | |
template += "\t\t\treturn new #{clazz.cls_name}[size];\n" | |
template += "\t\t}\n\n" | |
template += "\t\t@Override\n" | |
template += "\t\tpublic #{clazz.cls_name} createFromParcel(Parcel source) {\n" | |
template_builder = "" | |
clazz.attrs.each do |attr| | |
first_cap_name = getFirstUpcase(attr.name) | |
first_type_name = getFirstUpcase(attr.type) | |
if first_type_name.include? "List" | |
listtype_first_index = 1+first_type_name.index('<') | |
listtype_name = first_type_name[listtype_first_index..first_type_name.size-2] | |
template += "\t\t\tArrayList<#{listtype_name}> #{attr.name} = new ArrayList<#{listtype_name}>();\n" | |
template += "\t\t\tsource.readList(#{attr.name}, #{listtype_name}.class.getClassLoader());\n\n" | |
elsif first_type_name.include? "Entity" | |
template += "\t\t\t#{attr.type} #{attr.name} = source.readParcelable(#{attr.type}.class.getClassLoader());\n" | |
else | |
template += "\t\t\t#{attr.type} #{attr.name} = source.read#{first_type_name}();\n" | |
end | |
template_builder += "\t\t\t\t\t.set#{first_cap_name}(#{attr.name})\n" | |
end | |
template += "\n\t\t\treturn new Builder()\n" | |
template += template_builder | |
template += "\t\t\t\t\t.get#{clazz.cls_name}();\n" | |
template += "\t\t}\n" | |
template += "\t};\n\n" | |
template | |
end | |
def builder_template(i=0) | |
clazz = $env.clz_list[i] | |
cls_name = clazz.cls_name | |
instance_name = getFirstDowncase(cls_name) | |
attrs = clazz.attrs | |
lead_type = "\t" * get_lead_num(i) + "\t" | |
template = "#{lead_type}public static class Builder {\n\n" | |
template += "#{lead_type}\tprivate #{cls_name} #{instance_name} = new #{cls_name}();\n\n" | |
attrs.each do |attr| | |
first_cap_name = getFirstUpcase(attr.name) | |
template += "#{lead_type}\tpublic Builder set#{first_cap_name}(#{attr.type} #{attr.name}) {\n" | |
template += "#{lead_type}\t\t#{instance_name}.#{attr.name} = #{attr.name};\n" | |
template += "#{lead_type}\t\treturn this;\n" | |
template += "#{lead_type}\t}\n\n" | |
end | |
template += "#{lead_type}\tpublic #{cls_name} get#{cls_name}() {\n" | |
template += "#{lead_type}\t\treturn #{instance_name};\n" | |
template +="#{lead_type}\t}\n" | |
template += "#{lead_type}}\n\n" | |
template | |
end | |
def genBean | |
clazz_list=$env.clz_list | |
output_path = ARGV[1] | |
0.upto(clazz_list.size-1) do |i| | |
cur_clz = clazz_list[i] | |
output_file = File.new("#{output_path}/#{cur_clz.cls_name}\.java", "w") | |
output_file.puts print_cls_import(cur_clz.cls_import_advanced) | |
output_file.puts print_cls_head(i) | |
output_file.puts print_attrs(i) | |
output_file.puts get_template(i) | |
output_file.puts set_template(i) | |
output_file.puts parcel_template(i) | |
output_file.puts builder_template(i) | |
output_file.puts print_cls_end(0) | |
output_file.close | |
end | |
end | |
=begin | |
$clz_list = [] #类的容器 | |
$cur_clz = nil #当前类 | |
$attr = nil #当前属性 | |
$attr_index=0 #当前类的第几个属性 | |
$clz_index=0 #当前属于第几个类 | |
=end | |
File.open("#{ARGV[0]}", "r:UTF-8"){|f| | |
f.each_line do |line| | |
line = line.gsub("\n","") #去除换行符 | |
if /^Cls/ =~ line #碰到以Cls开头,表名以下的属性属于该类 | |
type_cls_names = line.split(":") #将该行分成两部分,第一部分为Cls,第二部分为类名集合,每个类名之间用-相连 | |
cls_names = type_cls_names[1].split("-") #获取类名集合 | |
# 类名之后的内容为类注释,尝试获取类注释,如果有的话 | |
if type_cls_names.size > 2 | |
cls_comment = type_cls_names[2] | |
$env.cur_clz_comment = cls_comment | |
end | |
cls_name = cls_names[cls_names.size-1] | |
$env.cur_clz = Clazz.new(cls_name) | |
$env.cur_clz.lead_cls_names = cls_names[0...cls_names.size-1] #获取前导类名集合 | |
$env.clz_list[$env.clz_index] = $env.cur_clz; | |
$env.clz_index += 1 | |
$env.attr_index = 0 #重置attr_index | |
else #将该类的属性,填充在该类中 | |
if $env.cur_clz == nil | |
puts "nil" | |
else | |
attr_type_name = line.split(":") | |
attr_name=attr_type_name[0] | |
attr_type=attr_type_name[1] | |
$env.attr = Attr.new(attr_type,attr_name) | |
$env.cur_clz.attrs[$env.attr_index] = $env.attr | |
$env.attr_index += 1 | |
# 如果包含List,则导入List包 | |
if (attr_type.include? "List") | |
$env.cur_clz.cls_import_advanced = 1 | |
end | |
# 如果当前类有注释 | |
if $env.cur_clz_comment != nil | |
$env.cur_clz.cls_comment = $env.cur_clz_comment | |
end | |
end | |
end | |
end | |
=begin | |
print_clz_list | |
puts get_template(0) | |
puts builder_template | |
=end | |
genBean | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment