#!/bin/env/python # coding=utf-8 """ 程序运行入口 """ from LogTool import logger from CodeGenerator import CodeGenerator from ErrorUtil import ErrorUtil import time import Target from ExcelConf import excel_conf logger.debug("gen start") # package_name = raw_input("Please input java package name(like com.xxx.xxx):") CodeGenerator.set_package_name(excel_conf.get("package_name")) CodeGenerator.set_protocol_file(excel_conf.get("protocol_file")) CodeGenerator.set_service_name(excel_conf.get("service_name")) CodeGenerator.set_option_comment(True) CodeGenerator.set_option_json_serialize(False) module_list = [] CodeGenerator.extend_import_module(module_list) start_time = time.clock() CodeGenerator.run(Target.Target_pmbank) CodeGenerator.run(Target.Target_openapi) CodeGenerator.run(Target.Target_normal) stop_time = time.clock() use_time = stop_time - start_time print "gen success, statics="
def init(target): """ 解析excel文件,收集要处理的数据, 为target目标对象生成dto :param target: 目标对象有:openapi\pmbank\通用 """ protocol_file = CodeTemplate.java_template.get("protocol_file") if os.path.isfile(protocol_file): excel_data = xlrd.open_workbook(protocol_file) sheets = excel_data.sheets() sheet_names = excel_data.sheet_names() sheet_num = len(sheets) if 0 >= sheet_num: logger.error("data not found in excel") return index = 0 protocol_data = [] while index < sheet_num: dto_num = 0 need_import_module = [] sheet_origin_name = sheet_names[index].strip() # 从excel读到的sheet名称,为unicode格式, 需转换为utf-8编码 sheet_origin_name = sheet_origin_name.encode('utf-8') sheet_name = excel_conf.get("sheets_name_dict").get( sheet_origin_name) if sheet_name is None: index += 1 logger.warn("sheet_name=%s not in dict, no need to parse" % sheet_origin_name) continue content = { "sheet_name": sheet_name, "dto_elems": [], "need_import_module": [], } table = sheets[index] nrows = table.nrows # 加载excel描述规则 row_format = excel_conf.get("sheets_row_format") if row_format is None: logger.error("miss option sheets_row_format") return min_field_num = row_format.get("field_min_num") if min_field_num is None: logger.error("miss option field_min_num") return field_pos = excel_conf.get("sheets_field_position") if field_pos is None: logger.error("miss option sheets_field_position") return pos_id = field_pos.get("field_id") pos_name = field_pos.get("field_name") pos_comment = field_pos.get("field_comment") pos_type = field_pos.get("field_type") if pos_id is None or pos_name is None or pos_type is None: logger.error( "miss field_id or field_name or field_type in sheets_field_position" ) return # 用于内嵌的文件 nest_dto_filename = "" nest_dto_fp = "" nest_dto_elems = [] nest_dto_import_module = [] lv2_nest_dto_filename = "" lv2_nest_dto_fp = "" lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 公共的解析逻辑,基于excel描述规则 for i in xrange(nrows): # 默认不需要生成嵌套的dto, 目前只支持2层嵌套 need_create_nest_dto = False lv2_need_create_nest_dto = False data = table.row_values(i) if len(data) < min_field_num: logger.warn( "sheet_name=%s row=%s miss some cols, you need at least %s cols" % (sheet_name, i, min_field_num)) continue # 字段位置id print type(data[pos_id]) dto_field_id = data[pos_id] print dto_field_id if data[pos_id] is None: logger.error("sheet_name=%s row=%s miss field_id" % (sheet_origin_name, i)) ErrorUtil.addInvalidFieldId( target, sheet_name, data[pos_name] if data[pos_name] is not None else "unknown") elif type(data[pos_id]) == int or str( data[pos_id]).strip().isdigit(): dto_field_id = int(data[pos_id]) elif type(data[pos_id]) == float: if CommonUtil.isFloat(dto_field_id): # 如果确实为浮点数, 则意味着需要生成嵌套的dto need_create_nest_dto = True else: tmp = str(data[pos_id]).strip() dot_count = tmp.count('.') if dot_count == 1: need_create_nest_dto = True elif dot_count == 2: need_create_nest_dto = True lv2_need_create_nest_dto = True else: print type(data[pos_id]) continue # 一层嵌套是否需要退出 if not need_create_nest_dto and not CommonUtil.is_empty( nest_dto_fp): nest_dto_content = { "sheet_name": nest_dto_filename, "dto_elems": nest_dto_elems, "need_import_module": nest_dto_import_module, } CodeGenerator.gen_code(nest_dto_content, target) # 二层嵌套是否需要退出 if not lv2_need_create_nest_dto and not CommonUtil.is_empty( lv2_nest_dto_fp): lv2_nest_dto_content = { "sheet_name": lv2_nest_dto_filename, "dto_elems": lv2_nest_dto_elems, "need_import_module": lv2_nest_dto_import_module, } CodeGenerator.gen_code(lv2_nest_dto_content, target) # 字段名校验 if CommonUtil.is_empty(data[pos_name]): logger.error( "sheet_name=%s have empty field_name, please check" % sheet_origin_name) ErrorUtil.addEmptyFieldName(target) continue dto_field_name = str(data[pos_name]).strip() dto_field_type = str( CodeTemplate.java_template.get("default_field_type" ) if CommonUtil. is_empty(data[pos_type]) else data[pos_type]).strip() # 字段类型校验--预处理完还是没有, 则过滤该行 if CommonUtil.is_empty(dto_field_type): ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) continue # 特殊处理( pos = dto_field_type.find('(') if pos > 0: dto_field_type = dto_field_type[0:pos] # 字段类型二次校验 -- 检查以'('号开始的类型 if 0 == pos: ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) # 字段注释 dto_field_comment = str("" if data[pos_comment] is None else data[pos_comment]).strip() # 当读到字段id为1,且当前尚未生成过Dto时,需 # 1.更新sheet_name # 2.dto计数加1 # 当读到字段id为1,且已生成过dto时,需 # 1.将已有的content内容加入protocol_data中 # 2.初始化content if 1 == dto_field_id: if 0 == dto_num: content[ "sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_request_filename_postfix") dto_num += 1 CodeGenerator.setRequestPropertyStyle(target) else: content["need_import_module"] = need_import_module need_import_module = [] CodeGenerator.gen_code(content, target) content[ "sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_response_filename_postfix") content["dto_elems"] = [] content["need_import_module"] = [] CodeGenerator.setResponsePropertyStyle(target) # 是否包含list类型字段 tmp_type = dto_field_type.lower() if tmp_type in ["list", "array"]: if lv2_need_create_nest_dto and "list" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("list") elif need_create_nest_dto and "list" not in nest_dto_import_module: nest_dto_import_module.append("list") else: if "list" not in need_import_module: need_import_module.append("list") dir_path = CodeTemplate.java_template.get( "default_file_path" ).get("output_" + target) % CodeGenerator.service_name if not os.path.exists(dir_path): os.makedirs(dir_path) # 为Array、List字段生成独立的dto文件 # 并使后续的小数点字段进入该dto内部 # 不支持嵌套array的情况, 所以这里只有为false时,才会生成dto, 否则前面生成的数据会被覆盖 if not need_create_nest_dto: nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" nest_dto_fp = open( dir_path + nest_dto_filename + ".java", "w+") nest_dto_elems = [] nest_dto_import_module = [] elif not lv2_need_create_nest_dto: lv2_nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" lv2_nest_dto_fp = open( dir_path + lv2_nest_dto_filename + ".java", "w+") lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 是否包含date类型 if tmp_type in ["t", "d", "date"]: if lv2_need_create_nest_dto and "date" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("date") elif need_create_nest_dto and "date" not in nest_dto_import_module: nest_dto_import_module.append("date") else: if "date" not in need_import_module: need_import_module.append("date") # 是否包含decimal类型 if tmp_type in ["b", "decimal", "bigdecimal"]: if lv2_need_create_nest_dto and "big_decimal" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("big_decimal") elif need_create_nest_dto and "big_decimal" not in nest_dto_import_module: nest_dto_import_module.append("big_decimal") else: if "big_decimal" not in need_import_module: need_import_module.append("big_decimal") if dto_field_name is None or dto_field_type is None: logger.error( "dto_field_name or dto_field_type miss, please check you protocol file" ) continue dto_elem = { "name": dto_field_name, "type": dto_field_type, "comment": dto_field_comment, } # 如果是嵌套的,则进入嵌套文件DTO中 if lv2_need_create_nest_dto: lv2_nest_dto_elems.append(dto_elem) elif need_create_nest_dto: nest_dto_elems.append(dto_elem) else: content["dto_elems"].append(dto_elem) # 单个sheet处理结束后,把未生成的文件生成出来 # 一层嵌套 if need_create_nest_dto and not CommonUtil.is_empty( nest_dto_fp): nest_dto_content = { "sheet_name": nest_dto_filename, "dto_elems": nest_dto_elems, "need_import_module": nest_dto_import_module, } CodeGenerator.gen_code(nest_dto_content, target) # 二层嵌套 if lv2_need_create_nest_dto and not CommonUtil.is_empty( lv2_nest_dto_fp): lv2_nest_dto_content = { "sheet_name": lv2_nest_dto_filename, "dto_elems": lv2_nest_dto_elems, "need_import_module": lv2_nest_dto_import_module, } CodeGenerator.gen_code(lv2_nest_dto_content, target) if dto_num > 0: content["need_import_module"] = need_import_module protocol_data.append(content) index += 1 return protocol_data else: logger.error("protocol_file=%s not exist" % protocol_file) print "protocol_file=%s not exist" % protocol_file return []
def init(target): """ 解析excel文件,收集要处理的数据, 为target目标对象生成dto :param target: 目标对象有:openapi\pmbank\通用 """ protocol_file = CodeTemplate.java_template.get("protocol_file") if os.path.isfile(protocol_file): excel_data = xlrd.open_workbook(protocol_file) sheets = excel_data.sheets() sheet_names = excel_data.sheet_names() sheet_num = len(sheets) if 0 >= sheet_num: logger.error("data not found in excel") return index = 0 protocol_data = [] while index < sheet_num: dto_num = 0 need_import_module = [] sheet_origin_name = sheet_names[index].strip() # 从excel读到的sheet名称,为unicode格式, 需转换为utf-8编码 sheet_origin_name = sheet_origin_name.encode('utf-8') sheet_name = excel_conf.get("sheets_name_dict").get(sheet_origin_name) if sheet_name is None: index += 1 logger.warn("sheet_name=%s not in dict, no need to parse" % sheet_origin_name) continue content = { "sheet_name": sheet_name, "dto_elems": [], "need_import_module": [], } table = sheets[index] nrows = table.nrows # 加载excel描述规则 row_format = excel_conf.get("sheets_row_format") if row_format is None: logger.error("miss option sheets_row_format") return min_field_num = row_format.get("field_min_num") if min_field_num is None: logger.error("miss option field_min_num") return field_pos = excel_conf.get("sheets_field_position") if field_pos is None: logger.error("miss option sheets_field_position") return pos_id = field_pos.get("field_id") pos_name = field_pos.get("field_name") pos_comment = field_pos.get("field_comment") pos_type = field_pos.get("field_type") if pos_id is None or pos_name is None or pos_type is None: logger.error("miss field_id or field_name or field_type in sheets_field_position") return # 用于内嵌的文件 nest_dto_filename = "" nest_dto_fp = "" nest_dto_elems = [] nest_dto_import_module = [] lv2_nest_dto_filename = "" lv2_nest_dto_fp = "" lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 公共的解析逻辑,基于excel描述规则 for i in xrange(nrows): # 默认不需要生成嵌套的dto, 目前只支持2层嵌套 need_create_nest_dto = False lv2_need_create_nest_dto = False data = table.row_values(i) if len(data) < min_field_num: logger.warn("sheet_name=%s row=%s miss some cols, you need at least %s cols" % ( sheet_name, i, min_field_num)) continue # 字段位置id print type(data[pos_id]) dto_field_id = data[pos_id] print dto_field_id if data[pos_id] is None: logger.error("sheet_name=%s row=%s miss field_id" % (sheet_origin_name, i)) ErrorUtil.addInvalidFieldId(target, sheet_name, data[pos_name] if data[pos_name] is not None else "unknown") elif type(data[pos_id]) == int or str(data[pos_id]).strip().isdigit(): dto_field_id = int(data[pos_id]) elif type(data[pos_id]) == float: if CommonUtil.isFloat(dto_field_id): # 如果确实为浮点数, 则意味着需要生成嵌套的dto need_create_nest_dto = True else: tmp = str(data[pos_id]).strip() dot_count = tmp.count('.') if dot_count == 1: need_create_nest_dto = True elif dot_count == 2: need_create_nest_dto = True lv2_need_create_nest_dto = True else: print type(data[pos_id]) continue # 一层嵌套是否需要退出 if not need_create_nest_dto and not CommonUtil.is_empty(nest_dto_fp): nest_dto_content = { "sheet_name": nest_dto_filename, "dto_elems": nest_dto_elems, "need_import_module": nest_dto_import_module, } CodeGenerator.gen_code(nest_dto_content, target) # 二层嵌套是否需要退出 if not lv2_need_create_nest_dto and not CommonUtil.is_empty(lv2_nest_dto_fp): lv2_nest_dto_content = { "sheet_name": lv2_nest_dto_filename, "dto_elems": lv2_nest_dto_elems, "need_import_module": lv2_nest_dto_import_module, } CodeGenerator.gen_code(lv2_nest_dto_content, target) # 字段名校验 if CommonUtil.is_empty(data[pos_name]): logger.error("sheet_name=%s have empty field_name, please check" % sheet_origin_name) ErrorUtil.addEmptyFieldName(target); continue dto_field_name = str(data[pos_name]).strip() dto_field_type = str(CodeTemplate.java_template.get("default_field_type") if CommonUtil.is_empty( data[pos_type]) else data[pos_type]).strip() # 字段类型校验--预处理完还是没有, 则过滤该行 if CommonUtil.is_empty(dto_field_type): ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) continue # 特殊处理( pos = dto_field_type.find('(') if pos > 0: dto_field_type = dto_field_type[0:pos] # 字段类型二次校验 -- 检查以'('号开始的类型 if 0 == pos: ErrorUtil.addInvalidFieldType(target, sheet_name, dto_field_name) # 字段注释 dto_field_comment = str("" if data[pos_comment] is None else data[pos_comment]).strip() # 当读到字段id为1,且当前尚未生成过Dto时,需 # 1.更新sheet_name # 2.dto计数加1 # 当读到字段id为1,且已生成过dto时,需 # 1.将已有的content内容加入protocol_data中 # 2.初始化content if 1 == dto_field_id: if 0 == dto_num: content["sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_request_filename_postfix") dto_num += 1 CodeGenerator.setRequestPropertyStyle(target) else: content["need_import_module"] = need_import_module need_import_module = [] CodeGenerator.gen_code(content, target) content["sheet_name"] = sheet_name + CodeTemplate.java_template.get( "default_response_filename_postfix") content["dto_elems"] = [] content["need_import_module"] = [] CodeGenerator.setResponsePropertyStyle(target) # 是否包含list类型字段 tmp_type = dto_field_type.lower() if tmp_type in ["list", "array"]: if lv2_need_create_nest_dto and "list" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("list") elif need_create_nest_dto and "list" not in nest_dto_import_module: nest_dto_import_module.append("list") else: if "list" not in need_import_module: need_import_module.append("list") dir_path = CodeTemplate.java_template.get("default_file_path").get("output_" + target) % CodeGenerator.service_name if not os.path.exists(dir_path): os.makedirs(dir_path) # 为Array、List字段生成独立的dto文件 # 并使后续的小数点字段进入该dto内部 # 不支持嵌套array的情况, 所以这里只有为false时,才会生成dto, 否则前面生成的数据会被覆盖 if not need_create_nest_dto: nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" nest_dto_fp = open(dir_path + nest_dto_filename + ".java", "w+") nest_dto_elems = [] nest_dto_import_module = [] elif not lv2_need_create_nest_dto: lv2_nest_dto_filename = CamelTransformTool.trans_underline_field_to_camel_classname( dto_field_name) + "DTO" lv2_nest_dto_fp = open(dir_path + lv2_nest_dto_filename + ".java", "w+") lv2_nest_dto_elems = [] lv2_nest_dto_import_module = [] # 是否包含date类型 if tmp_type in ["t", "d", "date"]: if lv2_need_create_nest_dto and "date" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("date") elif need_create_nest_dto and "date" not in nest_dto_import_module: nest_dto_import_module.append("date") else: if "date" not in need_import_module: need_import_module.append("date") # 是否包含decimal类型 if tmp_type in ["b", "decimal", "bigdecimal"]: if lv2_need_create_nest_dto and "big_decimal" not in lv2_nest_dto_import_module: lv2_nest_dto_import_module.append("big_decimal") elif need_create_nest_dto and "big_decimal" not in nest_dto_import_module: nest_dto_import_module.append("big_decimal") else: if "big_decimal" not in need_import_module: need_import_module.append("big_decimal") if dto_field_name is None or dto_field_type is None: logger.error("dto_field_name or dto_field_type miss, please check you protocol file") continue dto_elem = { "name": dto_field_name, "type": dto_field_type, "comment": dto_field_comment, } # 如果是嵌套的,则进入嵌套文件DTO中 if lv2_need_create_nest_dto: lv2_nest_dto_elems.append(dto_elem) elif need_create_nest_dto: nest_dto_elems.append(dto_elem) else: content["dto_elems"].append(dto_elem) if dto_num > 0: content["need_import_module"] = need_import_module protocol_data.append(content) index += 1 return protocol_data else: logger.error("protocol_file=%s not exist" % protocol_file) print "protocol_file=%s not exist" % protocol_file return []
#!/bin/env/python # coding=utf-8 """ 程序运行入口 """ from LogTool import logger from CodeGenerator import CodeGenerator from ErrorUtil import ErrorUtil import time import Target from ExcelConf import excel_conf logger.debug("gen start") # package_name = raw_input("Please input java package name(like com.xxx.xxx):") CodeGenerator.set_package_name(excel_conf.get("package_name")) CodeGenerator.set_protocol_file(excel_conf.get("protocol_file")) CodeGenerator.set_service_name(excel_conf.get("service_name")) CodeGenerator.set_option_comment(True) CodeGenerator.set_option_json_serialize(False) module_list = [ ] CodeGenerator.extend_import_module(module_list) start_time = time.clock() CodeGenerator.run(Target.Target_pmbank) CodeGenerator.run(Target.Target_openapi) CodeGenerator.run(Target.Target_normal) stop_time = time.clock() use_time = stop_time - start_time